如題,先看代碼示例 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博客
僅供學習參考?