在这种情况下:
var user = (from user in appContext.User
where user.username == Username
where user.enabled).FirstOrDefault();
SQL查询类似于:
SELECT * FROM User
EF检索所有记录并在where查询后进行。为什么呢?
如何只获取与where子句相对应的实体?
注意:appContext.User是ICollection
答案 0 :(得分:2)
首先,您使用的查询语法只是syntax-sugar。它将转换为以下代码:
appContext.User.Where(user => user.username== UserName).Where(user => user.isenabled);
编译时 appContext.User
是ICollection
是问题所在。 IEnumerable
和IQueryable
linq方法是扩展方法。这意味着调用方法的IEnumerable
或IQueryable
版本是在编译时确定的(运行时不是)。
即使appContext.User
在运行时是IQueryable
,也无关紧要,因为它在编译时被声明为ICollection
( impelments IEnumerable
),将调用IEnumerable
扩展方法。这些扩展方法采用Func<>
,这意味着您的lambda表达式将被编译为方法。
另一方面,如果appContext.User
在编译时是IQueryable
,则会使用IQueryable
扩展方法,因此您的lambda表达式将转换为表达式树因此,可以在实体框架的运行时进行评估。
另一方面,Laurent,我想给你一些荣誉,因为他们会在#34;&#34;并注意到查询不是您所期望的。太多的开发人员只是假设一切都按照他们的预期运行,然后他们为什么会遇到性能问题而感到困惑。
答案 1 :(得分:0)
如果appContext.User是IQueryable,那么该查询将不会产生select *
类型的查询。
如果您执行appContext.User.ToList().Where(user => user.username == Username)
之类的操作,则在应用之前,查询将返回您正在告知的所有记录,并IQueryable
将所有记录实现为对象(通过.ToList()
)过滤
您可以在数据库上运行探查器并添加实际输出吗?
答案 2 :(得分:0)
使用:
var user = (from user in appContext.Set<User>()
where user.username == Username
where user.enabled).FirstOrDefault();