sqlSugar ORM 空記錄子查詢後,緩存表生成SQL錯誤

 

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取出。

也沒太深入瞭解,只能是先在查詢空的時候加入恢復緩存的方法來應急用了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章