如何使用Entity Framework 7在代码中首先处理这两个模型?

问题

我正在编写将模拟库的概念ASP.NET 5 MVC6的certificate。 我正在使用CTP6和beta3。

如何使用代码优先方法在Entity Framework 7中定义它们的关系?

货架和书籍需要连接表。 在我看来,这个应用程序将一次考虑一个架子和自己的书籍。 换句话说,一个书架与书籍有一对多的关系。

楷模

货架型号:

public class Shelf { public int ShelfId { get; set; } public string ShelfName { get; set; } public ShelfType MyProperty { get; set; } public virtual List Books { get; set; } public DateTime Created { get; set; } public string CreatedBy { get; set; } public DateTime Updated { get; set; } public string UpdatedBy { get; set; } } 

书籍型号:

 public class Book { public int BookId { get; set; } public string BookName { get; set; } public string BookAuthor { get; set; } public string BookGenre { get; set; } public DateTime BookPublishedDate { get; set; } public string Description { get; set; } public DateTime Created { get; set; } public string CreatedBy { get; set; } public DateTime Updated { get; set; } public string UpdatedBy { get; set; } } 

目标

我想在ASP.NET 5中实现类似的function。由于TPH和其他function尚未在EF7中实现,我是否在正确的轨道上?

换句话说,我在想以下几点:

  • ShelfBookViewModel(毕竟我需要一个视图模型来显示一个书架和书籍,或者书本能够回到架子上)。 我可能只会将它命名为ShelfBook。 这似乎是错误的做法。
  • 我希望EF7能够弄清楚我有一个连接并为单独的关注点创建视图模型。 否则,这违反了SOLID代码的做法。 下面给出的东西(来自之前的链接)。
  • 加入表还没有在EF7中实现,我问的是徒劳的?

我无法让以下工作如下所示:

  modelBuilder.Entity() .HasMany(p => p.Shelfs) .WithMany(t => t.Books) .Map(mc => { mc.ToTable("ShelfJoinBook"); mc.MapLeftKey("ShelfId"); mc.MapRightKey("BookId"); }); 

感谢您抽出宝贵时间阅读我的问题。 我希望其他人觉得这很有用。

要回答有关多对多的问题,您应该按如下方式定义映射(并且必须更新模型类):

 modelBuilder.Entity() .HasMany(p => p.Books) .WithMany(t => t.Shelves) // doesn't exist .Map(mc => { mc.ToTable("BookShelves"); mc.MapLeftKey("ShelfId"); mc.MapRightKey("BookId"); }); 

这需要你添加一个ICollection Shelves { get; set; } ICollection Shelves { get; set; } Book 。 但是,如果您这样做,那么您将拥有以下内容(这是我的示例的MCVE版本):

 public class Shelf { public int ShelfId { get; set; } public virtual ICollection Books { get; set; } } public class Book { public int BookId { get; set; } public virtual ICollection Shelves { get; set; } } 

然后你不再需要映射,因为EF会按惯例为你生成所有关系,包括只在数据库本身可见的连接表。

但是 – 从您的实际模型类和围绕它们的讨论 – 看起来您真的只需要一对多,在这种情况下,您应该接受Pynt的答案,并忽略我的。

编辑

正如Gert Arnold在评论中指出的那样,EF7目前(不再是?)支持生成的连接表,这意味着我们必须自己动手,这无论如何都可能更好 。

这是我认为我可以从现在开始做自己的简单连接表的方式,如果EF不再为我做这些(警告 – 我只是想在这个问题上关闭循环……我不是打扰在编译器中尝试这个,所以YMMV):

 public class Shelf { public int ShelfId { get; set; } public virtual ICollection BookShelves { get; set; } public virtual IQueryable Books { get { return BookShelves.Where(s => s.ShelfId == ShelfId) .Select(s => s.Book); } } } public class Book { public int BookId { get; set; } public virtual ICollection BookShelves { get; set; } public virtual IQueryable Shelves { get { return BookShelves.Where(s => s.BookId == BookId) .Select(s => s.Shelf); } } } public class BookShelf { [Key] public int BookId { get; set; } [ForeignKey("BookId")] public Book Book { get; set; } [Key] public int ShelfId { get; set; } [ForeignKey("ShelfId")] public Shelf Shelf { get; set; } } 

我处理类似的情况,虽然它可能不符合您的需求。 我使用数据注释,因为我没有费心去学习如何通过lambda映射设置外键。 通过以下设置,您可以为每个书架设置一个书籍实例,并且书架可以包含许多书籍。 我已将关系属性移动到类的底部以便于可视化。

货架型号:

 public class Shelf { public int ShelfId { get; set; } public string ShelfName { get; set; } public ShelfType MyProperty { get; set; } public DateTime Created { get; set; } public string CreatedBy { get; set; } public DateTime Updated { get; set; } public string UpdatedBy { get; set; } public virtual ICollection Books { get; set; } } 

书籍型号:

 using System.ComponentModel.DataAnnotations.Schema; public class Book { public int BookId { get; set; } public string BookName { get; set; } public string BookAuthor { get; set; } public string BookGenre { get; set; } public DateTime BookPublishedDate { get; set; } public string Description { get; set; } public DateTime Created { get; set; } public string CreatedBy { get; set; } public DateTime Updated { get; set; } public string UpdatedBy { get; set; } public int ShelfId { get; set; } [ForeignKey("ShelfId")] public Shelf Shelf { get; set; } }