我有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"));
}
}
一点也不复杂。 Rota可以为其分配一个Employee和/或Department,所有这些都是使用Fluent配置的。我的所有关联都是正确的(架构是完美的),但我有一个奇怪的怪异。
当我执行myContext.Departments.FirstOrDefault()
并查看SQL Generated时,Employee&amp;上有一个 LEFT OUTER JOIN 。罗塔。这是为什么?我不希望它这样做。也许我的Fluent映射不正确?我已经尝试了各种各样的,但似乎无法弄明白。如果我想要一个可以加入部门的Rota对象,我会理解的。但不是相反!
如果我执行myContext.Departments.AsNoTracking().FirstOrDefault()
,则不执行 LEFT OUTER JOIN 。
任何想法的人?
干杯, d
答案 0 :(得分:5)
原因是映射不正确。看起来不错,但事实并非如此。请改用:
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"));
}
}
在创建数据库和数据库看起来正确时,您的映射被正确解释,但EF认为您将所有关系映射为一对一。这会混淆EF,它会生成用于一对一创建内部实体引用的查询。当您告诉EF依赖实体是可选的时,这些左连接对于一对一关系是必需的 - 除非加载其密钥,否则EF不知道它们是否存在。
答案 1 :(得分:0)
我绝不是专家,我只是在这里猜测。但是,您可以按照实体框架的方式尝试查询,然后以理想情况下查看查询并发布时间差异的方式进行尝试。也许实体框架在这里有所作为,但我对此表示怀疑。
答案 2 :(得分:0)
我有理论。关闭更改跟踪时,左外连接会消失。 Employee和Rota也提到了Department。
所以我的理论是,对于实体框架的更改跟踪尝试加载所有实体,并引用该部门,以防它必须将更新级联到部门。
换句话说,它认为对部门的更改可能会导致对Employee或Rota引用部门的更改,因此它会加载所有内容以防万一。