entity framework包含左连接是否可能?

我有以下表格

  1. ClassRoom(ClassID,ClassName)
  2. StudentClass(StudentID,ClassID)
  3. 学生(学生ID,学生姓名等)
  4. StudentDescription。 (StudentDescriptionID,StudentID,StudentDescription)

我想检索关于student == 1的所有信息

在sql我会做类似下面的事情并获得有关学生的所有信息。

select * from Student s join StudentClass sc on s.StudentID=sc.StudentID join ClassRoom c on sc.ClassID=c.ClassID left join StudentDescription sd on s.StudentID=sd.StudentID where s.StudentID=14 

现在我的问题。使用EF4我做了类似的事情,但无法使其工作。 你也可以做一个包含和一个左连接

尝试1

 private static StudentDto LoadStudent(int studentId) { StudentDto studentDto = null; using (var ctx = new TrainingContext()) { var query = ctx.Students .Include("ClassRooms") .Include("StudentDescriptions") .Where(x=>x.StudentID==studentId) .SingleOrDefault(); studentDto = new StudentDto(); studentDto.StudentId = query.StudentID; studentDto.StudentName = query.StudentName; studentDto.StudentDescription = ?? } return studentDto; } 

再次尝试2不完整和错误

 using (var ctx = new TrainingContext()) { var query = (from s in ctx.Students .Include("ClassRooms") join sd in ctx.StudentDescriptions on s.StudentID equals sd.StudentID into g from stuDesc in g.DefaultIfEmpty() select new { Name=s.StudentName, StudentId=s.StudentID, }).SingleOrDefault(); 

你可以看到我不知道我在这做什么。 如何将该Sql转换为EF查询?

对的,这是可能的。

首先, .Include使用您传递的导航属性执行LEFT OUTER JOIN。

这就是你如何在StudentStudentDescription之间明确地进行LEFT JOIN:

 var query = from s in ctx.Students from sd in s.StudentDescriptions.DefaultIfEmpty() select new { StudentName = s.Name, StudentDescription = sd.Description }; 

如您所见,它正在根据学生学生描述之间的实体关联执行JOIN。 在EF模型中,您应该在Student实体上有一个名为StudentDescriptions的导航属性。 上面的代码只是使用它来执行连接,并且默认为空。

代码与.Include基本相同。

请不要对LEFT JOINLEFT OUTER JOIN感到困惑

他们是一样的东西。

“OUTER”关键字是可选的,我相信它符合ANSI-92的兼容性。

只是。在查询中.Include您需要的所有内容:

 using (var ctx = new TrainingContext()) { studentDo = ctx.Students .Include("ClassRooms") .Include("StudentDescriptions") .Where(x=>x.StudentID==studentId) .Select(x => new StudentDto { StudentId = x.StudentId, StudentName = x.StudentName StudentDescription = x.StudentDescription.Description }) .SingleOrDefault(); } 

基本上,确保所有FK都表示为模型上的导航属性,如果是,则不需要进行任何连接。 您需要的任何关系都可以使用.Include完成。

我刚遇到这个问题,在我的情况下,EntityTypeConfiguration是错误的

我有:

  HasRequired(s => s.ClassRoom) .WithMany() .HasForeignKey(student => student.ClassRoomId); 

代替:

  HasOptional(s => s.ClassRoom) .WithMany() .HasForeignKey(student => student.ClassRoomId); 

似乎HasRequired在HasOptional进行LEFT JOIN时进行INNER JOIN。

究竟:

  1. 如果StudentDescription.StudentId可以为空 – > EF执行LEFT JOIN,即select * from Student s LEFT JOIN StudentDescription sd on s.StudentID=sd.StudentID
  2. 否则EF会进行INNER JOIN。