同一类型的多个关系

Multiple relations of same type

对于我的模型,我有 RealEstateTransactionAgent。一个 RealEstateTransaction 可以有一个 ListingAgent 和一个 SellingAgent.

我将如何建立我的模型来建立这种关系?是这样的吗?

public class Agent
{
    public long AgentId { get; set; }

    public List<RealEstateTransaction> ListingRealEstateTransactions { get; set; }

    public List<RealEstateTransaction> SellingRealEstateTransactions { get; set; }
}

public class RealEstateTransaction
{
    public long RealEstateTransactionId { get; set; }

    public long ListingAgentId { get; set; }
    public Agent ListingAgent { get; set; }

    public long SellingAgentId { get; set; }
    public Agent SellingAgent { get; set; }
}

这样做:

public class Agent
{
    public long AgentId { get; set; }

    public Virtual ICollection<RealEstateTransaction> ListingRealEstateTransactions { get; set; }

    public Virtual ICollection<RealEstateTransaction> SellingRealEstateTransactions { get; set; }
}

public class RealEstateTransaction
{
    public long RealEstateTransactionId { get; set; }

    [ForeignKey("ListingAgentId")]
    public Agent ListingAgent { get; set; }
    public long ListingAgentId { get; set; }


    [ForeignKey("SellingAgentId ")]
    public Agent SellingAgent { get; set; }
    public long SellingAgentId { get; set; }

}

Something like this?

确实如此。

但它需要一些额外的导航属性映射(FK 属性 名称遵循 EF Core 约定,因此不需要映射)。通常 EF Core 能够将关系两端的导航属性配对,但当您有两个关系到同一个实体时则不能。在这种情况下,您需要告诉主体的哪个导航 属性 对应于(相反)每个导航 属性 从属。

通常您可以通过数据注释([InverseProperty] 属性)或流利 API 来做到这一点。但是由于与同一实体的多个 FK 关系也引入了所谓的 多个级联路径 问题与 SqlServer(和其他一些数据库),您还需要关闭级联删除对于至少一个关系,这只能用流利的 API 来完成,所以所需的最小映射是这样的:

modelBuilder.Entity<Agent>()
    .HasMany(e => e.ListingRealEstateTransactions)
    .WithOne(e => e.ListingAgent)
    .OnDelete(DeleteBehavior.Restrict);

modelBuilder.Entity<Agent>()
    .HasMany(e => e.SellingRealEstateTransactions)
    .WithOne(e => e.SellingAgent)
    .OnDelete(DeleteBehavior.Restrict);

您可以跳过其中一个关系的 .OnDelete(DeleteBehavior.Restrict)(或将其更改为 DeleteBehavior.Cascade,这是此类必需关系的默认设置)。请注意,删除主体(在本例中为 Agent)需要首先手动删除具有 DeleteBehavior.Restrict.

的每个关系的所有相关依赖项

这是必填部分。或者,如果 RealEstateTransaction 实体仅用作标准的多对多 "link" 实体(没有其他属性并且 (ListingAgentId, SellingAgentId) 对是唯一的),您可以删除 RealEstateTransactionId PK 属性 并流畅配置复合PK:

modelBuilder.Entity<RealEstateTransaction>()
    .HasKey(e = new { e.ListingAgentId, e.SellingAgentId });

参考文献: