简体   繁体   English

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

[英]EF 6 - How to solve foreign key error for composite key?

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 我正在使用代码优先策略,.NET MVC 4.5和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: 当我要运行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 });

then, when I run update-database command everything is OK until first accees to the database via EF. 然后,当我运行update-database命令时,一切正常,直到首先通过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. 从表Product(ShopId,CategoryId)到表Category(CategoryId,ShopId)的外键约束'Product_Category'::映射不足:外键必须映射到概念上参与外键关联的某些AssociationSet或EntitySet。

What I now: 我现在要做什么:

  1. If I delete foreign key from Model class, EF still generate foreign key to the migration code. 如果我从Model类中删除外键,EF仍然会为迁移代码生成外键。 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) (即使在DB中表之间没有任何外键)

  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. 如果我将Product类属性CategoryId从int更改为string,EF将在表Product_CategoryId和Product_ShopId中生成新的两列,并将外键放在这些列上。 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. 我想从CategoryId和ShopId列中获得直接外键。

Really thx. 真的很感谢。 for any advice. 任何建议。

From your code, is there any specific reason why a product Or Category should inherit from DbContext ? 从您的代码中,是否有任何特定的原因为什么产品或类别应从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" 我怀疑失败的原因是“组合主键(产品中的一部分)也属于类别中外键(复合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; }
    }

Let me know if this what you are expecting. 让我知道这是您的期望吗。 and First thing at place is EF Migration Runner should throw exception ???? 并且最重要的是EF Migration Runner应该抛出异常?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM