首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实体框架计数效率

实体框架计数效率
EN

Stack Overflow用户
提问于 2017-12-22 11:36:51
回答 3查看 196关注 0票数 2

我从数据库中查询学校实体。然后,我尝试通过这样做来获取该学校的学生数量:

代码语言:javascript
复制
var school = context.schools.Where(s=>s.ID == 1).Single();
int cnt = school.students.Count();

但是我看到发送到数据库的查询获取了该学校的所有学生记录,并且计数是在应用程序服务器上完成的。

而下面的代码只是从数据库中查询COUNT(),这是理所应当的:

代码语言:javascript
复制
int cnt = context.students.Where(s=>s.schoolID == 1).Count();

为什么这两种方法会有如此大的不同?第一个查询不也应该使用COUNT()来提高效率吗?

注意:不查询学校实体是不可行的,因为我正在使用它的一些字段。

EN

回答 3

Stack Overflow用户

发布于 2017-12-22 13:46:12

学生通过LazyLoading工作,所以首先,你获取学生:school.students,然后在客户端.Count()他们,就像你已经写的那样。但是你可以这样修改你的代码,这将执行一次数据库之旅:

代码语言:javascript
复制
var answer = (from sch in context.schools
              where sch.ID == 1
              join st in context.students on sch.ID equals st.schoolID into subs
              from sub in subs.DefaultIfEmpty()
              group sub by new { sch.ID, sch.Name, sch.Location } into gr
              select new 
              {
                  gr.Key.Name,
                  gr.Key.Location,
                  Count = gr.Count(x => x != null)
              }).First();

sch.Namesch.Location -学校的字段,需要进一步使用

票数 2
EN

Stack Overflow用户

发布于 2017-12-22 15:59:09

查询在可能的最后时刻运行,以使它们尽可能高效-称为延迟加载-在您的第一个示例中,您的Single()调用迫使数据提供程序比您希望的要少一些延迟。

当您调用Single()时,您请求的是整个Student记录-所有学生记录列表中的第一条记录,因此查询必须运行(GET SchoolId, SchoolName, .... FROM SCHOOLS WHERE SchoolId = 1)才能获得该数据。然后调用Count(),除了只选择COUNT之外,重播查询。

相反,在第二个示例中,您只能在Where()调用之后调用Count()Where()不会强制执行查询,因为您还没有访问任何数据,因此数据提供程序只能在评估Count()之后对数据库执行GET COUNT类型的查询。

如何判断LINQ方法是否会“播放”你的查询?我记得的方式是,如果它返回IQueryable<T>,它将不会播放您的查询,其他任何内容,它都会。

票数 2
EN

Stack Overflow用户

发布于 2017-12-22 16:14:52

这一切都是关于延迟加载的,但其效果是双重的:

  1. context.schools.Where(s=>s.ID == 1).Single()将返回一个没有加载任何学生的学校实体(惰性加载第1部分)。但是,由于.students部分的原因,
  2. school.students.Count()必须访问所有学生的数据库-因为他们不是在第一行加载的,所以他们都将被加载(因为您隐式地请求了这一点-延迟加载部分2),然后Count()触发。

要减少调用次数,可以按照您的建议执行:int cnt = context.students.Where(s=>s.schoolID == 1).Count();,这将导致2个db调用,或者像在the original answer中那样创建分组结果

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47935544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档