我已经开始分手了我的" uber"上下文成为较小的焦点。在一个简单的场景中,我有Student
和Lectures
POCOS,我的EntityTypeConfiguration
在名为StudentsAndLectures
的新表中定义了两者之间的多对多关系。
这些表是我的超级上下文中定义的表关系网络的一部分。但是,我希望以更有针对性的方式管理学生及其讲座。
我的POCO课程如下。
public class Student
{
public Student()
{
Lecture = new List<Lecture>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Lecture> Lectures { get; set; }
}
public class Lecture
{
public Lecture()
{
Students = new List<Student>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
最后,我的实体键入mappers。
public class StudentMapper : EntityTypeConfiguration<Student>
{
public StudentMapper()
{
HasKey(x => x.Id);
HasMany(x => x.Lectures)
.WithMany(x => x.Students)
.Map(m =>
{
m.MapLeftKey("LectureId");
m.MapRightKey("StudentId");
m.ToTable("StudentsAndLectures");
});
Property(x => x.Name);
}
}
public class LectureMapper : EntityTypeConfiguration<Lecture>
{
public LectureMapper()
{
HasKey(x => x.Id);
HasMany(x => x.Students)
.WithMany(x => x.Lectures)
.Map(m =>
{
m.MapLeftKey("LectureId");
m.MapRightKey("StudentId");
m.ToTable("StudentsAndLectures");
});
Property(x => x.Name);
}
}
此外,My Focused上下文仅包含学生和讲座的DbSet。
我的问题,如果我使用我的焦点上下文查询下面的特定学生,我的.Lectures的导航属性将返回空。但是,如果我使用创建db的完整(超级)上下文,我的导航属性会根据需要延迟加载或急切加载。任何人都知道为什么会这样吗?
using(FocusedStudentContext db = new FocusedStudentContext())
{
var student = db.Students.Include(s => s.Lectures)
.FirstOrDefault(s => s.StudentID == 1234);
// Inspecting student here for the Lectures navigation property
// collection has 0 elements.
}
经过进一步的测试和实验后,我发现如果我包含了我的模型中存在的一个特定(没有其他)额外的DbSet
及其相关的ModelBuilder
配置,那么一切正常。 DbSet
适用于实体Registration
,并且具有Student
HasRequired (x => x.Student)
的导航属性。另一个问题是,如果我保留ModelBuilder
实体的Registration
配置,但从我的焦点上下文中删除DbSet<Registration>
,那么Lectures
的导航属性将再次停止添加。 (该集合有0个元素)。
我的困惑是,如何在我的Focused上下文中添加DbSet
会影响上面描述的表/实体的导航属性解析方式?我该如何解决这个问题。任何帮助将不胜感激。
答案 0 :(得分:1)
您只需要一个多对多映射,而不是两个。但即使你可以有两个映射,它们应该是相同的。在你的情况下,他们不是。这两个映射在MapLeftKey
和MapRightKey
中具有相同的列,但它们从不同的目的开始。只有LectureMapper
是正确的。
显然,StudentMapper
优先,我认为这是由映射添加到配置的顺序决定的。结果是EF正在通过联结表中的Lecture
值查找StudentId
:非常错误。我无法真正解释包含您描述的其他映射和实体的影响。我只是假设在不同情况下使EF首先采用其他映射。
但是让MapLeftKey
和MapRightKey
错误太容易了。我试图通过描绘它们来使它们分开:
Lecture HasMany Student
Left: LectureId Right: StudentId
MSDN说明不太有用,例如MapLeftKey
:
配置左外键列的名称。左外键指向HasMany调用中指定的导航属性的父实体
HasMany调用中指定的导航属性为Students
,属性的父级(或所有者)为Lecture
,由LectureId
标识...我去了可视化。
答案 1 :(得分:0)
更新我想我解决了这个但不是真的。我发现,如果我删除了学生和演讲中的显式映射到多个表,让EF做到这一点,现在情况正常。
HasMany(x =&gt; x.Students).WithMany(x =&gt; x.Lectures);