繁体   English   中英

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

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

我正在尝试创建一个链接表,该表将使我的产品表和附件表之间具有多对多关系。

我的课是这样的:

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

如果配件类型不同,则同一配件可以在一个产品上出现多次,这将在链接表中确定。 像这样:

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

这是正确的方法吗?

编辑

这是我在运行更新数据库时遇到的错误:

在表“ ProductAccessoryLinks”上引入FOREIGN KEY约束“ FK_dbo.ProductAccessoryLinks_dbo.Types_TypeId”可能会导致循环或多个级联路径。 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。 无法创建约束。 请参阅先前的错误。

这是导致错误的sql:ALTER TABLE [dbo]。[ProductAccessoryLinks]添加约束[FK_dbo.ProductAccessoryLinks_dbo.Types_TypeId] FOREIGN KEY([TypeId])参考[dbo]。[Types]([Id])删除级联

在您的情况下,您需要显式映射联结表。 您的模型将如下所示:

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

您可以通过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使您可以直接配置尝试的多对多关系。 因此,EF负责使用其要连接的表的适当键在数据库中构建连接表。 (键既是联接表的主键,又是指向联接表的外键)。 这样一来,您就可以在联接表中获取数据,而不必知道其存在。 但是,当您想对该表进行个性化设置(例如,添加一些其他属性)时,需要像上面显示的那样显式地映射它。

更新

当您具有级联删除的多个路径而最终尝试删除Types表中的同一行时,会导致该异常。 要解决该问题,我建议您在这篇文章中检查我的答案

暂无
暂无

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

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