2013-12-18 65 views
0

试图找出如何执行LINQ to Entities查询以获得与字段表有关的多对多关系。EF LINQ to Entites查询多对多关系

以下是域模型(我正在使用视图模型,但为此示例保持简单)。

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将为此创造一个实体。

延迟加载

我得到这个工作了延迟加载。导航属性已用“虚拟”关键字声明。

查询方式 - 工作!

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或)许多StudentCourses。

如果你知道我的意思,我不完全理解实体应该如何成形。 举例来说,我已经试过:

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

什么我需要是返回学生的实体StudentCourses集合然后可以被分配给学生,并传递给视图模型,然后查看。

真的很感谢任何帮助,因为我花了很多时间来解决这个问题。另外作为一个便笺,我使用SingleOrDefault()方法将var(IQueryable我认为)的结果强制转换为Student类型。这是铸造的首选方式吗?

回答

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); 

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

回答你的问题:我更喜欢在上面大多数时候使用FirstOrDefault。不同之处在于SingleOrDefault预期为exactly one result,否则引发异常,而如果找不到学生,FirstOrDefault将返回null

此外,由于Student是隐含的,您不需要<Student>类型参数。

+0

这工作,非常感谢。出于性能原因,我会限制列和筛选行,即减少从数据库返回的结果集,因此需要查询投影。 –

+0

为了学习Eager加载的其他人的利益,你也可以做嵌套包含。在上面的例子中,我们还包含一个SubCourse域模式,它是StudentCourses上的一个导航属性(它可能或可能不会与课程领域模型物理链接)。这里有一段代码可以带回一个学生,它是一个或多个StudentCourse(s),它是一个或多个课程,最后它是一个或多个子课程:var student =(从s in context .StudentID == id select s).Include(“StudentCourses.Course”)。Include(“StudentCourses.SubCourse”)。FirstOrDefault();' –