简体   繁体   English

实体框架代码首先使用额外的密钥进行多对多

[英]Entity framework code first many to many with extra key

I'm trying to create a linked table that will allow me to have a many to many relationship between my product and accessory tables. 我正在尝试创建一个链接表,该表将使我的产品表和附件表之间具有多对多关系。

My classes are like this: 我的课是这样的:

public class Product {
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Accessory> Accessories { get; set; }
}

public class Accessory {
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Machine> Machine { get; set; }
}

public class Type {
    public int Id { get; set; }
    public string Name { get; set; }
}

The same accessory can be on a product more than once if it is a different type, which will be determined in the link table. 如果配件类型不同,则同一配件可以在一个产品上出现多次,这将在链接表中确定。 Something like this: 像这样:

public class ProductAccessoryLink {
    public int productId {get; set;}
    public int accessoryId {get; set;}
    public int typeId {get; set}
    public int sort {get; set;}
    public string notes {get; set}
}

Is this the right approach. 这是正确的方法吗?

EDIT 编辑

This is the error I'm getting when I run update-database: 这是我在运行更新数据库时遇到的错误:

Introducing FOREIGN KEY constraint 'FK_dbo.ProductAccessoryLinks_dbo.Types_TypeId' on table 'ProductAccessoryLinks' may cause cycles or multiple cascade paths. 在表“ ProductAccessoryLinks”上引入FOREIGN KEY约束“ FK_dbo.ProductAccessoryLinks_dbo.Types_TypeId”可能会导致循环或多个级联路径。 Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。 Could not create constraint. 无法创建约束。 See previous errors. 请参阅先前的错误。

This is the sql causing the error: ALTER TABLE [dbo].[ProductAccessoryLinks] ADD CONSTRAINT [FK_dbo.ProductAccessoryLinks_dbo.Types_TypeId] FOREIGN KEY ([TypeId]) REFERENCES [dbo].[Types] ([Id]) ON DELETE CASCADE 这是导致错误的sql:ALTER TABLE [dbo]。[ProductAccessoryLinks]添加约束[FK_dbo.ProductAccessoryLinks_dbo.Types_TypeId] FOREIGN KEY([TypeId])参考[dbo]。[Types]([Id])删除级联

In your case you need to map explicitly the junction table. 在您的情况下,您需要显式映射联结表。 Your model would be like this: 您的模型将如下所示:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<ProductAccessoryLink> ProductAccessoryLinks { get; set; }
}

public class Accessory
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<ProductAccessoryLink> ProductAccessoryLinks { get; set; }
}

public class Type
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class ProductAccessoryLink 
{
    public int ProductId { get; set; }
    public int AccessoryId { get; set; }
    public int TypeId { get; set; }
    public int sort { get; set; }
    public string notes { get; set; }

    public virtual Type Type { get; set; }
    public virtual Product Product { get; set; }
    public virtual Accessory Accessory { get; set; }
}

And you could configure the relationships overriding the OnModelCreating method on your context this way: 您可以通过OnModelCreating方式在上下文中配置覆盖OnModelCreating方法的关系:

protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<ProductAccessoryLink>().HasKey(i => new { i.ProductId, i.AccesoryId, i.TypeId});

    modelBuilder.Entity<ProductAccessoryLink>()
       .HasRequired(i => i.Product)
       .WithMany(k => k.ProductAccessoryLinks)
       .HasForeignKey(i=>i.ProductId);

    modelBuilder.Entity<ProductAccessoryLink>()
       .HasRequired(i => i.Accesory)
       .WithMany(k => k.ProductAccessoryLinks)
       .HasForeignKey(i=>i.AccesoryId);

    modelBuilder.Entity<ProductAccessoryLink>()
       .HasRequired(i => i.Type)
       .WithMany()
       .HasForeignKey(i=>i.TypeId);
}

EF lets you configure directly many-to-many relationships of the way you were attempting to. EF使您可以直接配置尝试的多对多关系。 Thereby EF is responsible for build a join table in the database with the appropriate keys of the tables it's joining. 因此,EF负责使用其要连接的表的适当键在数据库中构建连接表。 (The keys are both primary keys of the join table and foreign keys pointing to the joined tables). (键既是联接表的主键,又是指向联接表的外键)。 That lets you to get your data across the join table without you having to be aware of its presence. 这样一来,您就可以在联接表中获取数据,而不必知道其存在。 But when you want to personalize that table (adding, for example, some additional properties), you need to map it explicitly as I show above. 但是,当您想对该表进行个性化设置(例如,添加一些其他属性)时,需要像上面显示的那样显式地映射它。

Update 更新

That exception is caused when you have multiple paths of cascade deletes that could end trying to delete the same row in the Types table. 当您具有级联删除的多个路径而最终尝试删除Types表中的同一行时,会导致该异常。 To resolve that problem I recommend you check my answer in this post 要解决该问题,我建议您在这篇文章中检查我的答案

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

相关问题 Entity Framework 5,Code First 多对多外键映射,具有额外的属性 - Entity Framework 5, Code First Many to Many foreign key mapping with extra property 实体框架代码优先的多对多表外键 - Entity Framework code-first foreign key to many to many table 实体框架多对多代码 - Entity Framework Many to Many Code FIrst 实体框架多对多-代码优先-迁移 - Entity Framework many to many - Code First - Migrations 实体框架-代码优先-共享主键一对多关系 - Entity Framework - Code first - One to Many relationship with shared primary key 实体框架与额外字段的多对多关系(数据库优先) - Entity Framework many to many relationship with extra field (Database First) 实体框架代码一个实体的“多对多” - Entity Framework Code First many to many for one entity 实体框架,代码优先,如何从多对多关系映射中向表添加主键? - Entity Framework, code-first, how to add primary key to table out of many-to-many relationship mapping? 实体框架6.x代码优先主键约束错误保存多对多字段 - Entity Framework 6.x Code First PRIMARY KEY constraint error saving Many to Many field 实体框架(代码优先)一对多-生成额外的字段,而不使用映射的键 - Entity Framework (Code First) one to many - generates extra fields instead of using mapped keys
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM