EF 6 - 如何解决复合键的外键错误?

时间:2014-04-29 20:17:27

标签: c# database entity-framework foreign-keys

我正在玩这个问题好几天,找不到任何解决方案。

我正在使用代码优先策略,.NET MVC 4.5和EF 6

我有两个带有复合键的模型:

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; }
}

当我要运行add-migration命令时,我在迁移文件夹中获取此代码:

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

然后,当我运行update-database命令时,一切正常,直到首先通过EF加入数据库。我会收到这个错误:

  

表Product的外键约束'Product_Category'(ShopId,   CategoryId)到表类别(CategoryId,ShopId)::不足   mapping:外键必须映射到某个AssociationSet或   EntitySets参与了一个外键关联   概念方面。

我现在的事:

  1. 如果我从Model类中删除外键,EF仍然会为迁移代码生成外键。问题仍然存在。

  2. 如果从生成的代码中删除外键以进行迁移。问题仍然存在。 (即使在DB中表之间没有任何外键)

  3. 如果我将Product类属性CategoryId从int更改为string,则EF将为表Product_CategoryId和Product_ShopId生成新的两列,并将外键放在这些列上。问题解决了......

  4. 真的不明白哪里有问题。当然我不希望在表格中包含这两列。我想从CategoryId和ShopId列中获得直接外键。

    真的是thx。任何建议。

1 个答案:

答案 0 :(得分:0)

从您的代码中,产品或类别应该从DbContext继承的具体原因是什么?此外,尝试以下,它将工作。我怀疑它失败的原因是"复合主键(在产品中)的一部分也是来自Category"的外键(Composite Fk)的一部分。

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; }
    }

如果这是你所期待的,请告诉我。第一件事就是EF Migration Runner应抛出异常????