【问题标题】:Mapping many to many relationship in entity framework code first首先在实体框架代码中映射多对多关系
【发布时间】:2013-10-28 22:35:25
【问题描述】:

我正在尝试在 EF 中进行测试,创建多对多关系,因为我总是映射一对一或一对多,我在互联网上有一个示例供尝试,该示例适用于插入寄存器,但我无法读取寄存器

这是我的课程,我不知道HashSet是什么,我在网站上得到了这个代码

public class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public ICollection<Course> CoursesAttending { get; set; }

    public Person()
    {
        CoursesAttending = new HashSet<Course>();
    }
}

public class Course
{
    public int CourseId { get; set; }
    public string Title { get; set; }

    public ICollection<Person> Students { get; set; }

    public Course()
    {
        Students = new HashSet<Person>();
    }
}

这是我的上下文

public class SchoolContext : DbContext
{
    public DbSet<Course> Courses { get; set; }
    public DbSet<Person> People { get; set; }

    public SchoolContext()
        : base("MyDb")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Course>().
            HasMany(c => c.Students).
            WithMany(p => p.CoursesAttending).
            Map(
                m =>
                {
                    m.MapLeftKey("CourseId");
                    m.MapRightKey("PersonId");
                    m.ToTable("PersonCourses");
                });

    }
}

当我插入寄存器时是对的

static void Main(string[] args)
{
    using (SchoolContext db = new SchoolContext())
    {
        Course math = new Course();
        Course history = new Course();
        Course biology = new Course();
        math.Title = "Math";
        history.Title = "History";
        biology.Title = "Biology";

        db.Courses.Add(math);
        db.Courses.Add(history);
        db.Courses.Add(biology);

        Person john = new Person();
        john.FirstName = "John";
        john.LastName = "Paul";
        john.CoursesAttending.Add(history);
        john.CoursesAttending.Add(biology);

        db.People.Add(john);
        db.SaveChanges();
    }
}

但是当我尝试为显示内容选择注册时,它不起作用,它什么也不打印

static void Main(string[] args)
{
    using (SchoolContext db = new SchoolContext())
    {
        Pearson p = db.Peasons.First();
        Console.WriteLine(p.CoursesAttending.First().Title);
    }
}

我检查了数据库,寄存器存在,是什么问题?

请先教我如何在多对多关系中与代码进行选择。

【问题讨论】:

  • 如果在多对多关系的导航属性上使用.Add(),EF会自动更新对应的联合表吗?
  • @Celdor EF 当然会更新相应的连接表。

标签: c# entity-framework ef-code-first many-to-many


【解决方案1】:

首先,您可能希望通过使集合虚拟来启用延迟加载:

public virtual ICollection<Course> CoursesAttending { get; set; }
public virtual ICollection<Person> Students { get; set; }

这允许 EF 从 Course 和 Person 创建派生类(代理),这些类使用逻辑覆盖集合以从数据存储中加载其数据。

当你这样做时,你会看到

Console.WriteLine(p.CoursesAttending.First().Title);

将执行一个单独的查询来填充CoursesAttending。

另外,或者另外,您可以决定通过急切加载来阻止往返数据库,如下所示:

Person p = db.Persons.Include(p => p.CoursesAttending).First();

一次性加载Person 和 CoursesAttending。

【讨论】:

  • 太棒了!这是工作!那么......为什么包含用于快速选择?我不明白如何使用包含
  • 顾名思义,Include 将属性包含在查询中。通常,使用一个 SQL 查询(带有连接)比获取对象并稍后在单独的查询中查询它们的关联对象更有效。
【解决方案2】:

删除您的类构造函数和 OnModelCreating 方法。 EF 处理多对多关系。你不需要做任何额外的事情。

【讨论】:

  • 使用数据注释可以默认给你一个时髦的命名约定,通过提供流畅的 api 代码,可以避免这种不需​​要的命名。
  • 这个答案是 IMO OT,根本没有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多