简体   繁体   English

为什么左外部加入?

[英]Why the Left Outer join?

weird one. 奇怪的一个。 (Probably not weird, at all) (可能根本不奇怪)

I have 3 objects, Employee, Rota and Department. 我有3个对象,员工,罗塔和部门。

public class Employee
{
    public int Id { get; set; }
    public String Name { get; set; }
    public virtual Department Department { get; set; }
}

internal class EmployeeMapping : EntityTypeConfiguration<Employee>
{
    public EmployeeMapping()
    {
        HasKey(a => a.Id);
        Property(a => a.Id).HasColumnName("UserId");

        HasRequired<Department>(a => a.Department).WithOptional().Map(a => a.MapKey("DepartmentId"));
    }
}

public class Department
{
    public int Id { get; set; }
    public String Name { get; set; }
}

internal class DepartmentMapping : EntityTypeConfiguration<Department>
{
    public DepartmentMapping()
    {
        HasKey(a => a.Id);
        Property(a => a.Id).HasColumnName("DepartmentId");
    }
}

public class Rota
{
    public int Id { get; set; }
    public virtual Employee Employee { get; set; }
    public virtual Department Department { get; set; }
}

internal class RotaMapping : EntityTypeConfiguration<Rota>
{
    public RotaMapping()
    {
        HasKey(a => a.Id);
        Property(a => a.Id).HasColumnName("RotaId");

        HasOptional<Employee>(a => a.Employee).WithOptionalDependent().Map(a => a.MapKey("EmployeeId"));
        HasOptional<Department>(a => a.Department).WithOptionalDependent().Map(a => a.MapKey("DepartmentId"));
    }
}

Not complicated, at all really. 一点也不复杂。 Rota can have an Employee and/or a Department assigned to it, all of this is configured using Fluent. Rota可以为其分配一个Employee和/或Department,所有这些都是使用Fluent配置的。 All of my associations are correct (the schema is perfect), however I have a weird oddity. 我的所有关联都是正确的(架构是完美的),但我有一个奇怪的怪异。

When I do a myContext.Departments.FirstOrDefault() and have a look at the SQL Generated, there is a LEFT OUTER JOIN on Employee & Rota. 当我执行myContext.Departments.FirstOrDefault()并查看SQL Generated时,Employee和Rota上有一个LEFT OUTER JOIN Why is this there? 这是为什么?
I don't want it to do this. 我不希望它这样做。 Maybe my Fluent mappings are incorrect? 也许我的Fluent映射不正确? I've tried all sorts, but can't seem to figure it out. 我已经尝试了各种各样的,但似乎无法弄明白。 I would understand it if I want a Rota object, that would join on the Department. 如果我想要一个可以加入部门的Rota对象,我会理解的。 But not the other way around! 但不是相反!

If I do myContext.Departments.AsNoTracking().FirstOrDefault() it doesn't do the LEFT OUTER JOIN's . 如果我执行myContext.Departments.AsNoTracking().FirstOrDefault()它不会执行LEFT OUTER JOIN

Any ideas guys? 有什么想法吗?

Cheers, D 干杯,D

The reason is incorrect mapping. 原因是映射不正确。 It looks correct but it is not. 看起来不错,但事实并非如此。 Use these instead: 请改用:

internal class EmployeeMapping : EntityTypeConfiguration<Employee>
{
    public EmployeeMapping()
    {
        HasKey(a => a.Id);
        Property(a => a.Id).HasColumnName("UserId");

        HasRequired<Department>(a => a.Department).WithMany()
                                                  .Map(a => a.MapKey("DepartmentId"));
    }
}

internal class RotaMapping : EntityTypeConfiguration<Rota>
{
    public RotaMapping()
    {
        HasKey(a => a.Id);
        Property(a => a.Id).HasColumnName("RotaId");

        HasOptional<Employee>(a => a.Employee).WithMany()
                                              .Map(a => a.MapKey("EmployeeId"));
        HasOptional<Department>(a => a.Department).WithMany()
                                                  .Map(a => a.MapKey("DepartmentId"));
    }
}

Your mapping is correctly interpreted when creating database and database looks correct but EF thinks that you map all relations as one-to-one. 在创建数据库和数据库看起来正确时,您的映射被正确解释,但EF认为您将所有关系映射为一对一。 That confuse EF and it will generate queries used for one-to-one to create internal entity references. 这会混淆EF,它会生成用于一对一创建内部实体引用的查询。 These left joins are necessary for one-to-one relation when you tell EF that dependent entities are optional - EF doesn't know if they exist unless it loads their keys. 当您告诉EF依赖实体是可选的时,这些左连接对于一对一关系是必需的 - 除非加载其密钥,否则EF不知道它们是否存在。

I am by no means an expert and I am just guessing here. 我绝不是专家,我只是在这里猜测。 But could you try the query the way entity framework is doing it and then try it the way you would ideally like to see the query and post the time differentials. 但是,您可以按照实体框架的方式尝试查询,然后以理想情况下查看查询并发布时间差异的方式进行尝试。 Maybe the entity framework is on to something here, but I doubt it. 也许实体框架在这里有所作为,但我对此表示怀疑。

I have theory. 我有理论。 The left outer join goes away when you turn off change tracking. 关闭更改跟踪时,左外连接会消失。 Also Employee and Rota have references to Department. Employee和Rota也提到了Department。

So my theory is that with change tracking on the Entity Framework tries to load all entities with a reference to the department in case it has to cascade an update to department. 因此,我的理论是,实体框架上的更改跟踪尝试加载所有实体,并引用该部门,以防它必须将更新级联到部门。

In other words it thinks that a change to a Department could cause a change to the Employee or Rota referencing the department so it loads everything just in case. 换句话说,它认为对部门的更改可能会导致对Employee或Rota引用部门的更改,因此它会加载所有内容以防万一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM