sqlSugar ORM 空记录子查询后,缓存表生成SQL错误

1 篇文章 0 订阅
1 篇文章 0 订阅

 

sqlSugar ORM

今天在开发中偶然发现了正常查询语句出现了错误,但是没改代码的情况下之前一直没问题呢,想了不出现错误和出现错误中间就改了一个参数。

public static SqlSugarClient GetInstance()
        {
            SqlSugarClient db = new SqlSugarClient(
                new ConnectionConfig()
                {
                    ConnectionString = DBConfigPool.ConnectionString,
                    DbType = SqlSugar.DbType.SqlServer,
                    InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
                    IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样我就不多解释了
                    IsShardSameThread = true//设为true相同线程是同一个SqlConnection
                                            //"server=118.178.94.27;Database=AltrainTest;Uid=sa;Pwd=string@111999"
                });

            return db;
        }

IsShardSameThread = true//设为true相同线程是同一个SqlConnection

为了做事务,改了这个参数后就出现了以下错误

这个错误是以下代码运行后生成的

Db.Updateable<MaterialSaleModel>()
                .Where(a => a.BuyerID == user.BuyerID && a.IsDelete == false && a.ID == MaterialSaleID)
                .SetColumns(a => a.ShowSaleNum == showSaleNum)
                .ExecuteCommand();

这是一条很正常的查询语句,每有问题,那问题就出现在其他地方。

在重现错误的时候发现只能我把数据库里测试数据全部错误后,现调试程序就出现了这个错误。

就是有数据的时候不出现,很郁闷的情况。

在不知试了多少次后发现是之前一个嵌套查询引起的。

var sq1 = Db.Queryable<MaterialSaleModel, MaterialModel>((a, b) => new object[] { SqlSugar.JoinType.Inner, a.MaterialID == b.ID && a.BuyerID == b.BuyerID && b.IsDelete == false })
                .Where(a => a.BuyerID == user.BuyerID && a.IsDelete == false && a.PlaceID == PlaceID)
                .Select<MaterialSaleInfo>();

            return Db.Queryable(sq1)
                .WhereIF(!string.IsNullOrEmpty(par.Filter), par.Filter)
                .OrderByIF(!string.IsNullOrEmpty(par.OrderInfo), par.OrderInfo)
                .ToPageList(par.PageIndex, par.PageSize, ref par.TotalNumber, ref par.TotalPage);

 这个查询且满足查出来记录是空才能触发错误。

protected ISugarQueryable<T> _As(string tableName, string entityName)
        {
            IsAs = true;
            OldMappingTableList = this.Context.MappingTables;
            this.Context.MappingTables = this.Context.Utilities.TranslateCopy(this.Context.MappingTables);
            if (this.Context.MappingTables.Any(it => it.EntityName == entityName))
            {
                this.Context.MappingTables.Add(this.Context.MappingTables.First(it => it.EntityName == entityName).DbTableName, tableName);
            }
            this.Context.MappingTables.Add(entityName, tableName);
            this.QueryableMappingTableList = this.Context.MappingTables;
            return this;
        }

以上是查询后把查询的表保存到缓存。

public virtual List<T> ToPageList(int pageIndex, int pageSize, ref int totalNumber)
        {
            _RestoreMapping = false;
            List<T> result = null;
            int count = this.Count();
            _RestoreMapping = true;
            QueryBuilder.IsDisabledGobalFilter = UtilMethods.GetOldValue(QueryBuilder.IsDisabledGobalFilter, () =>
            {
                QueryBuilder.IsDisabledGobalFilter = true;
                if (count == 0)
                {
                    result = new List<T>();                    
                }
                else
                    result = ToPageList(pageIndex, pageSize);

            });
            totalNumber = count;
            return result;
        }

只有有记录的情况下程序进入ToPageList()里面,再进入

protected void RestoreMapping()
        {
            if (IsAs && _RestoreMapping)
            {
                this.Context.MappingTables = OldMappingTableList == null ? new MappingTableList() : OldMappingTableList;
            }
        }

输出数据后会把旧的缓存赋值给缓存集合。

public virtual List<T> ToPageList(int pageIndex, int pageSize, ref int totalNumber)
       {
            _RestoreMapping = false;
            List<T> result = null;
            int count = this.Count();
            _RestoreMapping = true;
            QueryBuilder.IsDisabledGobalFilter = UtilMethods.GetOldValue(QueryBuilder.IsDisabledGobalFilter, () =>
            {
                QueryBuilder.IsDisabledGobalFilter = true;
                if (count == 0)
                {
                    result = new List<T>();
                    RestoreMapping();
                }
                else
                    result = ToPageList(pageIndex, pageSize);

            });
            totalNumber = count;
            return result;
        }

所以问题就是空记录的时候没有把旧缓存赋值给缓存集合,也不知道作者是有其他作用还是什么情况。

这样的情况下后面的方法如果用到同名的缓存表,但又不是之前的语句时,就会读取缓存的SQL语句

internal string GetClassString(DbTableInfo tableInfo, ref string className)
        {
            string classText;
            var columns = this.Context.DbMaintenance.GetColumnInfosByTableName(tableInfo.Name);
            if (this.Context.IgnoreColumns.HasValue())
            {
                var entityName = this.Context.EntityMaintenance.GetEntityName(tableInfo.Name);
                columns = columns.Where(c =>
                                         !this.Context.IgnoreColumns.Any(ig => ig.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase) && c.DbColumnName == ig.PropertyName)
                                        ).ToList();
            }
            classText = this.ClassTemplate;
            string ConstructorText = IsDefaultValue ? this.ConstructorTemplate : null;
            if (this.Context.MappingTables.HasValue())
            {
                var mappingInfo = this.Context.MappingTables.FirstOrDefault(it => it.DbTableName.Equals(tableInfo.Name, StringComparison.CurrentCultureIgnoreCase));
                if (mappingInfo.HasValue())
                {
                    className = mappingInfo.EntityName;
                }
                if (mappingInfo != null)
                {
                    classText = classText.Replace(DbFirstTemplate.KeyClassName, mappingInfo.EntityName);
                }
            }

这里就是后面读取缓存同名的时候把之前的SQL取出。

也没太深入了解,只能是先在查询空的时候加入恢复缓存的方法来应急用了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值