Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架包含与左连接这是可能的吗?_C#_Entity Framework_Left Join - Fatal编程技术网

C# 实体框架包含与左连接这是可能的吗?

C# 实体框架包含与左连接这是可能的吗?,c#,entity-framework,left-join,C#,Entity Framework,Left Join,我有下列表格 教室(ClassID,ClassName) StudentClass(StudentID,ClassID) 学生(学生ID、学生姓名等) 学生描述。(StudentDescriptionID,StudentID,StudentDescription) 我想检索有关student==1的所有信息 在sql中,我会像下面这样做,并获得关于学生的所有信息 select * from Student s join StudentClass sc on s.StudentID=sc.St

我有下列表格

  • 教室(ClassID,ClassName)
  • StudentClass(StudentID,ClassID)
  • 学生(学生ID、学生姓名等)
  • 学生描述。(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我做了类似的事情,但无法让它工作。 还可以进行include和left连接吗

    尝试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
    使用您传递的导航属性进行左外连接

    这是在Student和StudentDescription之间显式执行左连接的方式:

    如您所见,它基于学生和学生描述之间的实体关联执行联接。在EF模型中,在学生实体上应该有一个名为学生描述的导航属性。上面的代码只是使用它来执行连接,如果为空,则默认为空

    代码与
    基本相同。包括

    请不要将左连接与左外连接混淆。

    它们是一样的东西。

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

    只需
    。在查询中包含所需的所有内容:

    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都表示为模型上的导航属性,如果是这样,则不需要进行任何连接。您需要的任何关系都可以通过
    完成。具体包括

  • 如果StudentDescription.StudentId可为空->EF执行左联接,即从学生的左联接StudentDescription sd中选择*s.StudentId=sd.StudentId
  • 否则EF不进行内部连接

  • 我只是遇到了这个问题,在我的例子中,是EntityTypeConfiguration出错了

    我有:

       HasRequired(s => s.ClassRoom)
                    .WithMany()
                    .HasForeignKey(student => student.ClassRoomId);
    
    而不是:

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

    似乎HasRequired创建了一个内部连接,而HasOptional创建了一个左连接。

    如果您想要一个1对1的关系,您可以简单地映射您的外部Id并使其为空

    public int? MyForeignClassId { get; set; }
    public MyForeignClass MyForeignClass { get; set; }
    

    感谢您的时间和回复。包含示例非常有效!!但是第一个会产生交叉连接。我可能完全错了,但是当你做两个from时,它不会产生交叉连接吗?我不理解这句话:“首先,.Include做左外连接,”。据我所知。Include执行内部联接。不,
    。Include
    执行外部联接。如果包含一个恰好为空(不在那里)的属性,则仍将返回原始属性。好吧,真正的答案是这取决于-这取决于所包含链接的可空性。如果可以为null,则左连接,如果不可以为null,则内部连接。这个答案是完全错误的,需要更新@拉尔斯是对的。如果导航属性的键可为null,并且实体映射使用WithOptional,则EF使用的查询将使用左联接。如果导航属性的键不可为NULL,或者实体映射使用WithRequired,则它将使用内部联接。如果将FK属性标记为[Required]属性,则它也会执行内部联接(只有当数据库中的DB架构和实体类之间不匹配时,该属性为NULL时,这才起作用)。要获取外部联接,您应该使用“GroupJoin”方法而不是“Join”。您应该在数据库表和实体类上将外键设置为可空。谢谢。。。。。。
    public int? MyForeignClassId { get; set; }
    public MyForeignClass MyForeignClass { get; set; }