EF LINQ to Entities查询多对多关系

时间:2013-12-18 09:30:46

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

试图找出如何对多个关系进行LINQ to Entities查询,该关系与字段表有结合。

下面是Domains模型(我正在使用View模型,但在本例中保持简单)。

Student Domain model
StudentID (PK)
ICollection<StudentCourse> StudentCourses

StudentCourse Domain model
StudentCourseID (PK)
StudentID (FK)
CourseID (FK)
ForAdult
ForSeniour
Description

Course Domain model
CourseID (PK)
ICollection<StudentCourse> StudentCourses

注意:

  • 由于联结表(即StudentCourse)包含两个外键以外的字段,因此EF将为此创建一个实体。

延迟加载

我已经将这个用于延迟加载。导航属性已使用'virtual'关键字声明。

查询方式 - 有效!

var student = (from s in context.Students
               where s.StudentID == id
               select s).SingleOrDefault<Student>()

方法方法 - 有效!

Student student = context.Students.Find(id);

投影

但是,出于性能原因,我希望通过投影来做到这一点,即减少到数据库的次数。

我真的被困在如何编写LINQ to Entities查询以返回1名学生(1或)许多学生课程。

如果你知道我的意思,我不完全明白应该如何塑造实体。 例如,我尝试过:

var myvar = from s in context.Students
            from sc in s.StudentCourses
            where s.StudentID == id
            select s

我需要的是返回Student的实体,其中包含StudentCourses集合,然后可以将其分配给Student并传递给View模型,然后传递给View。

真的很感激任何帮助,因为我花了很多时间试图解决这个问题。

另外作为旁注,我正在使用SingleOrDefault()方法将var的结果(我认为是IQueryable)转换为类型Student。这是投射的首选方式吗?

1 个答案:

答案 0 :(得分:1)

您可以使用Include方法让EF热切地加载相关实体。

所以使用你的LINQ例子:

var student = (from s in context.Students
               where s.StudentID == id
               select s).Include("StudentCourses").FirstOrDefault();

使用扩展方法:

var student = context.Students.Include("StudentCourses").FirstOrDefault(id);

返回的Student实例将使用相关实体填充StudentCourses集合。这应该只调用一个将表连接在一起的SQL查询。

回答你的问题:我更喜欢在上面大部分时间使用FirstOrDefault。区别在于SingleOrDefault会期望exactly one result并且会引发异常,而如果找不到学生则FirstOrDefault会返回null

此外,由于隐式转换为Student,因此您不需要<Student>类型参数。