I have this product class which has a list of products associated.
eg:
Product = StarWar
AssociatedProducts = Episode V: The Empire Strikes Back,
I think your classes are not right.
1 Problem: Why EF generates the table with extra columns?
In that case EF is using TPH strategy. Take a look at this link http://blogs.msdn.com/b/alexj/archive/2009/04/15/tip-12-choosing-an-inheritance-strategy.aspx
2 Problem: What is my mistake ? Is this a good way to associate a product ?
Your mapping should be something like this:
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public virtual ICollection<ProductAssociation> AssociatedProducts { get; set; }
public virtual ICollection<ProductAssociation> 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<Product> Products { get; set; }
public DbSet<ProductAssociation> ProductsAssociations { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.HasKey(i => i.ProductId);
modelBuilder.Entity<ProductAssociation>()
.HasKey(i => new {i.ProductId, i.ProductAssociatedId });
modelBuilder.Entity<Product>()
.HasMany(i => i.AssociatedProducts)
.WithRequired(i => i.ProductAssociated)
.HasForeignKey(i => i.ProductAssociatedId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Product>()
.HasMany(i => i.ProductsAssociatedThisProduct)
.WithRequired(i => i.Product)
.HasForeignKey(i => i.ProductId)
.WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
}
Seed
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();