文章出處

1.問題的現象

 public class LinqHepler<T> where T:class
    {
        private EFDBContext _context = null;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        public LinqHepler(EFDBContext context)
        {
            _context = context;
       
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public IQueryable<T> LoadEntities(Func<T, bool> whereLambda)
        {
            return _context.Set<T>().Where(whereLambda).AsQueryable();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public IQueryable<T> LoadEntitiesExpression(Expression<Func<T, bool>> whereLambda)
        {
            return _context.Set<T>().Where(whereLambda).AsQueryable();
        }
    }

 

[HttpGet]
        [Route("LinqWhere")]
        public IActionResult LinqWhere()
        {
            string uname = "";
            _context.UserInfo.Where(c => c.UserName == uname).ToList();//帶條件
            LinqHepler<UserInfo> linqHepler = new LinqHepler<UserInfo>(_context);
            linqHepler.LoadEntities(c => c.UserName == uname).ToList();//查全表
            linqHepler.LoadEntitiesExpression(c => c.UserName == uname).ToList();//不查全表
            return Ok();
        }

生產的sql

2017-10-11T02:59:22.495010Z 2328 Query SELECT `c`.`UserId`, `c`.`UserName`, `c`.`UserPwd`
FROM `UserInfo` AS `c`
WHERE `c`.`UserName` = ''
2017-10-11T02:59:22.538041Z 2328 Query SELECT `u`.`UserId`, `u`.`UserName`, `u`.`UserPwd`
FROM `UserInfo` AS `u`
2017-10-11T02:59:22.551050Z 2328 Query SELECT `c`.`UserId`, `c`.`UserName`, `c`.`UserPwd`
FROM `UserInfo` AS `c`
WHERE `c`.`UserName` = ''

 

可見,第一個是用EF對象直接調用Linq的擴展方法Where可以生成對應的Where條件,

第二個用泛型傳遞要查學的實體類型和Where條件去查詢,這時沒有生產對應的Where條件的sql

第三個加了Expession類型包裝Func對象有生產Where sql

 

參考大神的解釋

園友問:EF寫linq的時候,生成的SQL不帶where條件,給全表都查出來的,請問這是什么原因

0
懸賞園豆:50 [已解決問題] 瀏覽: 575次
我用的數據倉儲,我的查詢linq如下:
//查詢
public IQueryable<T> Query(Func<T, bool> wherelambda)
{
return db.Set<T>().AsNoTracking<T>().Where<T>(wherelambda).AsQueryable();
}
我的linq是調用該查詢方法,但是通過ef sql攔截生成的SQL是全表掃描,而通過監測 sql profile生成的sql也是不帶SQL

答:宏觀的解釋是Expression內部是專門有個解析器privoder,會根據條件解析成相應sql并執行到數據庫,而Func這個破委托類型沒有這種專業的sql解析器,沒法生成你想要的sql,直接是等默認全表加載后在內存中篩選。

總結

框架是照超來的,結果發現有很大的問題,可能是之前檢索問題的方式不對,或者是這個問題太簡單了,竟然很久才找到答案,原來是linq的基礎知識;

果然還是不能照抄照搬,我后來查看linq的所有方法參數中都帶有這個關鍵字,希望對大家有幫助;

 

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


全站熱搜
創作者介紹
創作者 大師兄 的頭像
大師兄

IT工程師數位筆記本

大師兄 發表在 痞客邦 留言(0) 人氣()