简体   繁体   English

当一个实体具有复合主键时,Entity Framework Core 中的多对多关系

[英]Many-to-many relationship in Entity Framework Core when one entity has composite primary key

I have the following classes:我有以下课程:

public class InvoiceLine
{
    public Guid Id { get; set; }

    public int LineNumber { get; set; }    

    public List<ProductCode> ProductCodes { get; set; }    
}

public class ProductCode
{
    public string Category { get; set; }
    public string Value { get; set; }
}

In the case of ProductCode the Category and the Value are together the primary key.ProductCode的情况下, CategoryValue是主键。

I set this up in the DbContext :我在DbContext中进行了DbContext

modelBuilder.Entity<ProductCode>()
            .HasKey(pc => new { pc.Category, pc.Value });

One InvoiceLine can have many product codes but a product code can be used for various InvoiceLine s.一个InvoiceLine可以有多个产品代码,但一个产品代码可以用于各种InvoiceLine

In EF Core I have to create a join entity with the ids and entitites:在 EF Core 中,我必须使用 ID 和实体创建一个连接实体:

public class InvoiceLineProductCode
{
    public Guid InvoiceLineId { get; set; }
    public InvoiceLine InvoiceLine { get; set; }
    public ProductCode ProductCode { get; set; }            
}

How can I set the ProductCodeId ?如何设置ProductCodeId

Adding composite FK is similar to adding single column FK.添加复合 FK 类似于添加单列 FK。

Start by adding the PK column(s) of the referenced entity:首先添加引用实体的 PK 列:

public class InvoiceLineProductCode
{
    public Guid InvoiceLineId { get; set; }
    public InvoiceLine InvoiceLine { get; set; }
    public string ProductCodeCategory { get; set; } // <--
    public string ProductCodeValue { get; set; } // <--
    public ProductCode ProductCode { get; set; }
}

Then define the composite join entity PK as usual:然后像往常一样定义复合连接实体PK:

modelBuilder.Entity<InvoiceLineProductCode>()
    .HasKey(e => new { e.InvoiceLineId, e.ProductCodeCategory, e.ProductCodeValue });

Also don't forget to change the Invoice collection navigation property type:另外不要忘记更改Invoice集合导航属性类型:

public class InvoiceLine
{
    public Guid Id { get; set; }
    public int LineNumber { get; set; }    
    public List<InvoiceLineProductCode> ProductCodes { get; set; } // <--
}

and since the names match EF Core conventions, you are done.并且由于名称与 EF Core 约定匹配,因此您已完成。 In cases they don't, the full configuration of the relationship ProductCode -> InvoiceLineProductCode would be like this:如果他们不这样做,关系ProductCode -> InvoiceLineProductCode的完整配置将是这样的:

modelBuilder.Entity<InvoiceLineProductCode>()
    .HasOne(e => e.ProductCode)
    .WithMany()
    .HasForeignKey(e => new { e.ProductCodeCategory, e.ProductCodeValue })
    .IsRequired()
    .OnDelete(DeleteBehavior.Cascade);

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

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