为什么左外部加入?

奇怪的一个。 (可能根本不奇怪)

我有3个对象,员工,罗塔和部门。

public class Employee { public int Id { get; set; } public String Name { get; set; } public virtual Department Department { get; set; } } internal class EmployeeMapping : EntityTypeConfiguration { public EmployeeMapping() { HasKey(a => a.Id); Property(a => a.Id).HasColumnName("UserId"); HasRequired(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 { 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 { public RotaMapping() { HasKey(a => a.Id); Property(a => a.Id).HasColumnName("RotaId"); HasOptional(a => a.Employee).WithOptionalDependent().Map(a => a.MapKey("EmployeeId")); HasOptional(a => a.Department).WithOptionalDependent().Map(a => a.MapKey("DepartmentId")); } } 

一点也不复杂。 Rota可以为其分配一个Employee和/或Department,所有这些都是使用Fluent配置的。 我的所有关联都是正确的(架构是完美的),但我有一个奇怪的怪异。

当我执行myContext.Departments.FirstOrDefault()并查看SQL Generated时,Employee&Rota上有一个LEFT OUTER JOIN 。 为什么会这样?
我不希望它这样做。 也许我的Fluent映射不正确? 我尝试了各种各样的,但似乎无法弄明白。 如果我想要一个可以加入部门的Rota对象,我会理解的。 但不是相反!

如果我执行myContext.Departments.AsNoTracking().FirstOrDefault()它不执行LEFT OUTER JOIN

任何想法的家伙?

干杯,D

原因是映射不正确。 看起来不错,但事实并非如此。 请改用:

 internal class EmployeeMapping : EntityTypeConfiguration { public EmployeeMapping() { HasKey(a => a.Id); Property(a => a.Id).HasColumnName("UserId"); HasRequired(a => a.Department).WithMany() .Map(a => a.MapKey("DepartmentId")); } } internal class RotaMapping : EntityTypeConfiguration { public RotaMapping() { HasKey(a => a.Id); Property(a => a.Id).HasColumnName("RotaId"); HasOptional(a => a.Employee).WithMany() .Map(a => a.MapKey("EmployeeId")); HasOptional(a => a.Department).WithMany() .Map(a => a.MapKey("DepartmentId")); } } 

在创建数据库和数据库看起来正确时,您的映射被正确解释,但EF认为您将所有关系映射为一对一。 这会混淆EF,它会生成用于一对一创建内部实体引用的查询。 当您告诉EF依赖实体是可选的时,这些左连接对于一对一关系是必需的 – 除非加载其密钥,否则EF不知道它们是否存在。

我绝不是专家,我只是在这里猜测。 但是,您可以按照entity framework的方式尝试查询,然后以理想情况下查看查询并发布时间差异的方式进行尝试。 也许entity framework在这里有所作为,但我对此表示怀疑。

我有理论。 关闭更改跟踪时,左外连接会消失。 Employee和Rota也提到了Department。

因此,我的理论是,entity framework上的更改跟踪尝试加载所有实体,并引用该部门,以防它必须将更新级联到部门。

换句话说,它认为对部门的更改可能会导致对Employee或Rota引用部门的更改,因此它会加载所有内容以防万一。