【问题标题】:EF 6 - How to solve foreign key error for composite key?EF 6 - 如何解决复合键的外键错误?
【发布时间】:2014-06-15 23:16:40
【问题描述】:

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

我使用的是代码优先策略,.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 (ShopId, CategoryId) 转表 Category(CategoryId, ShopId):: 不足 映射:外键必须映射到某个 AssociationSet 或 参与外键关联的实体集 概念方面。

现在的我:

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

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

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

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

真的很感谢。任何建议。

【问题讨论】:

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


    【解决方案1】:

    从您的代码中,产品或类别应继承自 DbContext 是否有任何具体原因?另外,请尝试以下方法,它会起作用。我怀疑它失败的原因是“复合主键的一部分(在产品中)也是类别中外键(复合 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 应该抛出异常????

    【讨论】:

    • 是的,就是这样!对你的问题。从模型类中的 DbContext 继承是错误的。谢谢你的建议。你有权利。主键的一部分不能是外键的一部分。现在它像我预期的那样工作。配置类中的 Seed 方法引发了异常。所以迁移中的所有代码都进行了,但是当EF第一次连接到数据库时(无论是什么表),都会抛出关于产品类别中坏键的异常。谢谢。再次。你节省了我很多时间!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2014-08-22
    相关资源
    最近更新 更多