Question

I'm playing with this problem for days and can't find any solution.

I'm using code first strategy, .NET MVC 4.5 and EF 6

I've two models with composite keys:

public class Category : DbContext
{
    [Key, Column(Order = 0),DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CategoryId { get; set; }

    [Key, Column(Order = 1)]
    public int ShopId { get; set; }

    public string Name { get; set; }  
}

public class Product : DbContext
{
  [Key, Column(Order = 0),DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  public int ProductId { get; set; }

  [Key, Column(Order = 1)]
  public int ShopId { get; set; }

  public int CategoryId { get; set; }

  [ForeignKey("CategoryId, ShopId")]        
  public virtual Category Category { get; set; }
}

when I going to run add-migration command I get this code in the migration folder:

 CreateTable(
  "dbo.Categories",
   c => new
   {
    CategoryId = c.Int(nullable: false, identity: true),
    ShopId = c.Int(nullable: false),
    Name = c.String(nullable: false, maxLength: 5)                  
   })
   .PrimaryKey(t => new { t.CategoryId, t.ShopId });

   CreateTable(
     "dbo.Products",
      c => new
      {
        ProductId = c.Int(nullable: false, identity: true),
        ShopId = c.Int(nullable: false),
        CategoryId = c.Int(nullable: false)
      })
      PrimaryKey(t => new { t.ProductId, t.ShopId })
      .ForeignKey("dbo.Categories", t => new { t.CategoryId, t.ShopId }, cascadeDelete: true)               
      .Index(t => new { t.ShopId, t.CategoryId });

then, when I run update-database command everything is OK until first accees to the database via EF. I'll get this error:

Foreign key constraint 'Product_Category' from table Product (ShopId, CategoryId) to table Category (CategoryId, ShopId):: Insufficient mapping: Foreign key must be mapped to some AssociationSet or EntitySets participating in a foreign key association on the conceptual side.

What I now:

  1. If I delete foreign key from Model class, EF still generate foreign key to the migration code. Problem persist.

  2. If I delete foreign key from generated code for migration. Problem still persist. (even if in DB is not any foreign key between tables)

  3. If I change in Product class attribute CategoryId from int to string, EF will generate new two columns to the table Product_CategoryId and Product_ShopId and put foreign key on these columns. Problem solved....

Really don't understant where's problem. Of course I don't want to have these two columns in table. I wanna have direct foreign key from CategoryId and ShopId columns.

Really thx. for any advice.

Was it helpful?

Solution

From your code, is there any specific reason why a product Or Category should inherit from DbContext ? Also, try the below and it will work. The reason i am suspecting why it failed is "A part of the Composite Primary Key (in Product) is also a part of Foreign Key (Composite Fk) from Category"

public class SampleContext : DbContext
    {
        public IDbSet<Category> Categories { get; set; }
        public IDbSet<Product> Products { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
             base.OnModelCreating(modelBuilder);
        }
    }
    public class Category
    {
        [Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int CategoryId { get; set; }
        [Key, Column(Order = 1)]
        public int ShopId { get; set; }
        public string Name { get; set; }
    }
    public class Product 
    {
        [Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int ProductId { get; set; }
        public int ShopId { get; set; }
        public int CategoryId { get; set; }
        [ForeignKey("CategoryId, ShopId")]
        public virtual Category Category { get; set; }
    }

Let me know if this what you are expecting. and First thing at place is EF Migration Runner should throw exception ????

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top