当前位置:   article > 正文

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

sqlsugarclient异常

 

sqlSugar ORM

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

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

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

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

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

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

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

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

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

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

  1. var sq1 = Db.Queryable<MaterialSaleModel, MaterialModel>((a, b) => new object[] { SqlSugar.JoinType.Inner, a.MaterialID == b.ID && a.BuyerID == b.BuyerID && b.IsDelete == false })
  2. .Where(a => a.BuyerID == user.BuyerID && a.IsDelete == false && a.PlaceID == PlaceID)
  3. .Select<MaterialSaleInfo>();
  4. return Db.Queryable(sq1)
  5. .WhereIF(!string.IsNullOrEmpty(par.Filter), par.Filter)
  6. .OrderByIF(!string.IsNullOrEmpty(par.OrderInfo), par.OrderInfo)
  7. .ToPageList(par.PageIndex, par.PageSize, ref par.TotalNumber, ref par.TotalPage);

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

  1. protected ISugarQueryable<T> _As(string tableName, string entityName)
  2. {
  3. IsAs = true;
  4. OldMappingTableList = this.Context.MappingTables;
  5. this.Context.MappingTables = this.Context.Utilities.TranslateCopy(this.Context.MappingTables);
  6. if (this.Context.MappingTables.Any(it => it.EntityName == entityName))
  7. {
  8. this.Context.MappingTables.Add(this.Context.MappingTables.First(it => it.EntityName == entityName).DbTableName, tableName);
  9. }
  10. this.Context.MappingTables.Add(entityName, tableName);
  11. this.QueryableMappingTableList = this.Context.MappingTables;
  12. return this;
  13. }

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

  1. public virtual List<T> ToPageList(int pageIndex, int pageSize, ref int totalNumber)
  2. {
  3. _RestoreMapping = false;
  4. List<T> result = null;
  5. int count = this.Count();
  6. _RestoreMapping = true;
  7. QueryBuilder.IsDisabledGobalFilter = UtilMethods.GetOldValue(QueryBuilder.IsDisabledGobalFilter, () =>
  8. {
  9. QueryBuilder.IsDisabledGobalFilter = true;
  10. if (count == 0)
  11. {
  12. result = new List<T>();
  13. }
  14. else
  15. result = ToPageList(pageIndex, pageSize);
  16. });
  17. totalNumber = count;
  18. return result;
  19. }

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

  1. protected void RestoreMapping()
  2. {
  3. if (IsAs && _RestoreMapping)
  4. {
  5. this.Context.MappingTables = OldMappingTableList == null ? new MappingTableList() : OldMappingTableList;
  6. }
  7. }

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

  1. public virtual List<T> ToPageList(int pageIndex, int pageSize, ref int totalNumber)
  2. {
  3. _RestoreMapping = false;
  4. List<T> result = null;
  5. int count = this.Count();
  6. _RestoreMapping = true;
  7. QueryBuilder.IsDisabledGobalFilter = UtilMethods.GetOldValue(QueryBuilder.IsDisabledGobalFilter, () =>
  8. {
  9. QueryBuilder.IsDisabledGobalFilter = true;
  10. if (count == 0)
  11. {
  12. result = new List<T>();
  13. RestoreMapping();
  14. }
  15. else
  16. result = ToPageList(pageIndex, pageSize);
  17. });
  18. totalNumber = count;
  19. return result;
  20. }

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

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

  1. internal string GetClassString(DbTableInfo tableInfo, ref string className)
  2. {
  3. string classText;
  4. var columns = this.Context.DbMaintenance.GetColumnInfosByTableName(tableInfo.Name);
  5. if (this.Context.IgnoreColumns.HasValue())
  6. {
  7. var entityName = this.Context.EntityMaintenance.GetEntityName(tableInfo.Name);
  8. columns = columns.Where(c =>
  9. !this.Context.IgnoreColumns.Any(ig => ig.EntityName.Equals(entityName, StringComparison.CurrentCultureIgnoreCase) && c.DbColumnName == ig.PropertyName)
  10. ).ToList();
  11. }
  12. classText = this.ClassTemplate;
  13. string ConstructorText = IsDefaultValue ? this.ConstructorTemplate : null;
  14. if (this.Context.MappingTables.HasValue())
  15. {
  16. var mappingInfo = this.Context.MappingTables.FirstOrDefault(it => it.DbTableName.Equals(tableInfo.Name, StringComparison.CurrentCultureIgnoreCase));
  17. if (mappingInfo.HasValue())
  18. {
  19. className = mappingInfo.EntityName;
  20. }
  21. if (mappingInfo != null)
  22. {
  23. classText = classText.Replace(DbFirstTemplate.KeyClassName, mappingInfo.EntityName);
  24. }
  25. }

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/134860
推荐阅读
  

闽ICP备14008679号