Linq To EF 用泛型时生成的Sql会查询全表的问题_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > Linq To EF 用泛型时生成的Sql会查询全表的问题

Linq To EF 用泛型时生成的Sql会查询全表的问题

 2017/10/11 11:43:07  圣叹&北京  程序员俱乐部  我要评论(0)
  • 摘要:1.问题的现象publicclassLinqHepler<T>whereT:class{privateEFDBContext_context=null;///<summary>//////</summary>///<paramname="context"></param>publicLinqHepler(EFDBContextcontext){_context=context;}///<summary>//////<
  • 标签:问题 SQL 泛型

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的所有方法参数中都带有这个关键字,希望对大家有帮助;

 

 

发表评论
用户名: 匿名