.NET仓储层在 using 块中创建 SqlSugarClient 的风险
如题,先看代码示例 using
块的使用
public ISugarQueryable<T> GetSet(Expression<Func<T, bool>> whereExpression = null)
{using (SqlSugarClient dbClient = SqlSugarInstance.GetInstance()){var query = dbClient.Queryable<T>();if (whereExpression != null){query = query.Where(whereExpression);}return query;}
}
使用 using
导致返回的 ISugarQueryable<T>
会因为连接释放而失效
你在 using
块中创建了 SqlSugarClient
,然后返回了基于它创建的 ISugarQueryable<T>
。但 using
会在方法结束时释放资源,这意味着你返回的查询对象里的连接已经被释放,后续在调用 .ToList()
、.First()
等方法时会抛异常或行为不确定。
🎯 调用方写法
var entity = _IWI_ZoneFolderRepository.GetSet(s => s.ZoneFolderCode.Equals(zoneFolderRemoveModel.FolderCode)).Take(1).ToList().FirstOrDefault();
🎯 为什么现在没出问题?
因为 SqlSugar 的 ISugarQueryable<T>
是个延迟执行(lazy evaluation)的查询对象,但你在调用完 .GetSet()
后 马上调用了 .Take(1).ToList()
,所以真正执行 SQL 查询的时机仍然落在了 using
块内部那条连接还有效的时候。
这就像是:
var query = db.Queryable<T>(); // 还没执行 SQL
var result = query.ToList(); // 这才执行 SQL,必须连接还活着
你现在这用法,是 立即执行型消费,所以目前没翻车。
✅ 最保险的写法
你有两种路径:
方式 1:调用者控制连接(推荐)
public ISugarQueryable<T> GetSet(SqlSugarClient dbClient, Expression<Func<T, bool>> where = null)
{var query = dbClient.Queryable<T>();if (where != null) query = query.Where(where);return query;
}
然后在调用方:
using var db = SqlSugarInstance.GetInstance();
var entity = _repo.GetSet(db, x => x.Id == 1).Take(1).ToList().FirstOrDefault();
方式 2:改为立即执行,返回结果
public T GetOne(Expression<Func<T, bool>> where)
{using var db = SqlSugarInstance.GetInstance();return db.Queryable<T>().Where(where).FirstOrDefault();
}
✅ 总结建议
情况 | 建议做法 |
---|---|
想要返回 ISugarQueryable<T> | 不要在方法内部 using 释放连接 |
想在方法里执行查询 | 使用 ToList() / FirstOrDefault() 立即执行,返回结果 |
想安全复用查询表达式 | 由调用方提供 SqlSugarClient ,连接生命周期在外层控制 |
🔍using 块的本意请参考这篇
.NET下 using 块的作用-CSDN博客
仅供学习参考