entity framework – Fluent APi – 使用2 FK创建表格

我有这个产品类,其中包含相关产品列表。

例如:

产品= StarWar

AssociatedProducts =第五集:帝国反击,第六集:绝地归来,第七集:原力觉醒

但EF使用一些额外的列生成数据库。

这是我的产品类别:

public class Product { public int Id { get; set; } public string Name { get; set; } public string ShortDescription { get; set; } public string FullDescription { get; set; } public decimal UnitPrice { get; set; } ...... public virtual ICollection AssociatedProducts { get; set; } ...... } 

这是我的AssociatedProduct类:

 public class AssociatedProducts { public int Id { get; set; } public int ProductId { get; set; } public int AssociatedProductId { get; set; } public int DisplayOrder { get; set; } public DateTime CreatedOn { get; set; } public virtual Product Products { get; set; } public virtual Product AssociatedProductsId { get; set; } } 

这是我对AssocietedProduct类的映射:

 public AssociatedProductsMap() { // Primary Key HasKey(a => a.Id); // Properties Property(a => a.CreatedOn).IsRequired(); Property(a => a.ProductId).IsRequired(); Property(a => a.AssociatedProductId).IsRequired(); Property(a => a.DisplayOrder).IsRequired(); //Relationship HasRequired(a => a.Products) .WithMany(p => p.Products) .HasForeignKey(a => a.ProductId) .WillCascadeOnDelete(false); HasRequired(a => a.AssociatedProductsId) .WithMany(p => p.AssociatedProducts) .HasForeignKey(a => a.AssociatedProductId) .WillCascadeOnDelete(false); //Table ToTable("AssociatedProducts"); } 

这就是我播种的方式:

 var associetedProducts = new List { new AssociatedProducts {ProductId= 1, AssociatedProductId = 3, DisplayOrder = 1, CreatedOn = DateTime.Now}, new AssociatedProducts {ProductId= 1, AssociatedProductId = 4, DisplayOrder = 2, CreatedOn = DateTime.Now}, new AssociatedProducts {ProductId= 1, AssociatedProductId = 5, DisplayOrder = 3, CreatedOn = DateTime.Now} } new List { new Product {Name = "StarWar", ShortDescription = "...", FullDescription = "P.......", UnitPrice = 15m, AssociatedProducts = associetedProducts}, new Product {Name = "StarWar Episode V", ShortDescription = "...", FullDescription = "P.......", UnitPrice = 15m}, new Product {Name = "StarWar Episode VI", ShortDescription = "...", FullDescription = "P.......", UnitPrice = 15m}, new Product {Name = "StarWar Episode VII", ShortDescription = "...", FullDescription = "P.......", UnitPrice = 15m}, }.ForEach(a => context.Products.AddOrUpdate(a)); context.SaveChanges(); 

这是我对AssociatedProductsId表的期望:ID + ProductId(FK)+ AssociatedProductsId(FK)+ date + ……

在此处输入图像描述

但这就是我得到的: 在此处输入图像描述

我的错是什么? 这是关联产品的好方法吗?

我认为你的课程不对。

1问题:为什么EF会生成带有额外列的表?

在那种情况下,EF正在使用TPH策略。 看一下这个链接http://blogs.msdn.com/b/alexj/archive/2009/04/15/tip-12-choosing-an-inheritance-strategy.aspx

2问题:我的错误是什么? 这是关联产品的好方法吗?

你的映射应该是这样的:

 public class Product { public int ProductId { get; set; } public string Name { get; set; } public virtual ICollection AssociatedProducts { get; set; } public virtual ICollection ProductsAssociatedThisProduct { get; set; } } public class ProductAssociation { public int ProductId { get; set; } public int ProductAssociatedId { get; set; } public DateTime CreationDate { get; set; } public virtual Product Product { get; set; } public virtual Product ProductAssociated { get; set; } } public class Context : DbContext { public Context() : base("Model2") { } public DbSet Products { get; set; } public DbSet ProductsAssociations { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity() .HasKey(i => i.ProductId); modelBuilder.Entity() .HasKey(i => new {i.ProductId, i.ProductAssociatedId }); modelBuilder.Entity() .HasMany(i => i.AssociatedProducts) .WithRequired(i => i.ProductAssociated) .HasForeignKey(i => i.ProductAssociatedId) .WillCascadeOnDelete(false); modelBuilder.Entity() .HasMany(i => i.ProductsAssociatedThisProduct) .WithRequired(i => i.Product) .HasForeignKey(i => i.ProductId) .WillCascadeOnDelete(false); base.OnModelCreating(modelBuilder); } } 

种子

 var product1 = new Product() { Name = "StarWars", ProductId = 1 }; var product2 = new Product() { Name = "StarWars II", ProductId = 2 }; context.ProductsAssociations.AddOrUpdate(new ProductAssociation { Product = product1, CreationDate = DateTime.Now, ProductAssociated = product2 }); context.Products.AddOrUpdate(product1); context.Products.AddOrUpdate(product2); context.SaveChanges();