同一类型的多个关系
Multiple relations of same type
对于我的模型,我有 RealEstateTransaction
和 Agent
。一个 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 });
参考文献:
对于我的模型,我有 RealEstateTransaction
和 Agent
。一个 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 });
参考文献: