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();