多对多表格,DbContext和实体框架以及Linq的复杂投影

时间:2013-02-28 21:50:56

标签: linq entity-framework many-to-many

我有一个DbContext与这四个多对多相关的实体:

Classes <-> Students
Classes <-> Assignments
Classes <-> Contents
Classes <-> Announcements

现在我需要一个Linq代码(或者更好!),这将给我们最后3个分配最后3个目录最后3个公告

另一方面,学生登录网站,我们想向他/她展示他/她在其中学习的每个课程的最后作业,内容,公告。

此代码不正确,但可能有助于您了解我的需求。此代码还需要多次运行(50ms不是很多?):

编辑:代码几乎是正确的,所以转而回答,看看已接受的答案。任何其他(更好,更快)的解决方案都值得赞赏。

提前致谢。

2 个答案:

答案 0 :(得分:0)

您最好与学生一起开始查询:

from s in db.Students
where s.StudentId == CurrentUser
from c in s.Classes
from as in c.Assignments.OrderByDescending(As => As.Id).Take(3)
from co in c.Contents.OrderByDescending(Co => Co.Id).Take(3)
from an in c.Announcements.OrderByDescending(An => An.Id).Take(3)
select new { <selected properties> }

最后一部分(选定的属性)很重要。通过仅选择属性的子集,可以缩小数据库中的结果集。如果没有这个,您将创建一个非常宽且长的结果集,因为(SQL)查询中有大量的连接。

答案 1 :(得分:0)

根据@ Gert Arnold 推荐,我更改了一些代码:

  • 以学生
  • 开始查询
  • 通过更改所选属性缩小结果范围
db.Students.Where(st => st.StudentId.Equals(CurrentUser)).SelectMany(S => S.Classes, (S, C) => new
{
    Name = C.Name,
    Assignments = C.Assignments.Select(AS => new { AS.Id, AS.Name }).OrderByDescending(As => As.Id).Take(3),
    Contents = C.Contents.Select(Co => new { Co.Id, Co.Title }).OrderByDescending(Co => Co.Id).Take(3),
    Announcements = C.Announcements.Select(An => new { An.Id, An.Title }).OrderByDescending(An => An.Id).Take(3)
});