1

我已经开始将我的“超级”语境分解成更小的重点语境。在一个简单的场景中,我StudentLecturesPOCOS 和我EntityTypeConfiguration在一个名为StudentsAndLectures.

这些表是在我的 uber 上下文中定义的表关系网络的一部分。但是,我想以更有针对性的方式和有针对性的背景来管理学生和他们的讲座。

下面是我的 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; }
}

最后,我的实体类型映射器。

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 context 包含仅适用于学生和讲座的 DbSet。

我的问题,如果我使用我的重点上下文查询如下特定学生,我的 .Lectures 导航属性返回空。但是,如果我使用创建数据库的完整(超级)上下文,我的导航属性会按照我的意愿延迟加载或急切加载。有谁知道为什么会这样?

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具有导航属性的实体。另一个转折是,如果我保留实体的配置,但从我的重点上下文中删除,那么我的导航属性将停止再次添加。(该集合有 0 个元素)。StudentHasRequired (x => x.Student)ModelBuilderRegistrationDbSet<Registration>Lectures

我的困惑是,DbSet在我的重点上下文中添加一个如何影响我的导航属性为上述表/实体解析的方式?我该如何解决这个问题。任何帮助将不胜感激。

4

2 回答 2

1

您只需要一个多对多映射,而不是两个。但是即使您可以有两个映射,它们也应该是相同的。在你的情况下,他们不是。MapLeftKey两个映射在和中具有相同的列MapRightKey,但它们从不同的末端开始。只有LectureMapper是正确的。

显然,StudentMapper优先,我认为这取决于将映射添加到配置中的顺序。效果是 EF 正在通过联结表中Lecture的值查找 s :非常错误。StudentId我无法真正解释包含您描述的其他映射和实体的效果。我只是假设在不同的情况下使EF首先采用其他映射。

但这太容易出错了MapLeftKeyMapRightKey我试图通过想象将它们分开:

Lecture            HasMany    Student
Left: LectureId               Right: StudentId

MSDN 描述不太有用,例如MapLeftKey

为左外键配置列的名称。左外键指向 HasMany 调用中指定的导航属性的父实体

HasMany 调用中指定的导航属性是Students,该属性的父(或所有者)是Lecture,由LectureId...标识。我去可视化。

于 2014-04-15T19:22:05.483 回答
0

更新我想我解决了这个问题,但不是真的。我发现,如果我删除 Student 和 Lectures 多对多表上的显式映射并让 EF 执行此操作,那么现在一切正常。

HasMany(x => x.Students).WithMany(x => x.Lectures);

于 2014-04-14T17:41:01.430 回答