[英]Is it possible to set up a navigation property without the foreign key?
是否可以有两个(或多个)相同类型的导航属性?
我的模型看起来像这样......
public class Agreement
{
public int Id { get; set; }
public Guid? BuyerId { get; set; }
public Guid? SellerId { get; set; }
public AgreementInfo ByerAgreementInfo { get; set; }
public AgreementInfo SellerAgreementInfo { get; set; }
}
public class AgreementInfo
{
// PK is AgreementId and OwnerActorId combined.
public int AgreementId { get; set; }
public Guid OwnerActorId { get; set; }
public string Name { get; set; }
}
...我试图通过匹配AgreementId和ByerId/SellerId来包含导航属性...
modelBuilder.Entity<Agreement>().HasOne(x => x.ByerAgreementInfo).WithOne().HasForeignKey<Agreement>(x => new {x.Id, x.ProviderId});
modelBuilder.Entity<Agreement>().HasOne(x => x.SellerAgreementInfo).WithOne().HasForeignKey<Agreement>(x => new { x.Id, x.RequesterId });
...但这会导致循环依赖。
有没有办法在不使用外键的情况下包含这些属性? 或者是否有另一种解决方案(除了向信息表添加一个 id 列)允许我使用信息表行作为协议类中的导航属性?
有很多方法可以实现您想要的。 您可以在您的子项上使用具有InverseProperty
属性的数据注释,在您的父项上使用ForeignKey
属性,或者在模型构建器中以任何一种方式使用流畅的语法。 我倾向于尽可能使用属性(数据注释)(这只是我个人的喜好),我发现它需要查看实际模式本身中的关系(尽管其他人可能不会)。
使用ForeignKey
属性:
public class Agreement
{
...
[ForeignKey("ByerAgreementInfo ")]
public int ByerAgreementInfoId { get; set; }
public AgreementInfo ByerAgreementInfo { get; set; }
[ForeignKey("SellerAgreementInfo ")]
public int SellerAgreementInfoId { get; set; }
public AgreementInfo SellerAgreementInfo { get; set;
}
使用InverseProperty
属性:
public class AgreementInfo
{
...
[InverseProperty("ByerAgreementInfo ")]
public ICollection<Agreement> Sellers { get; set; }
[InverseProperty("SellerAgreementInfo ")]
public ICollection<Agreement> Buyers { get; set; }
}
如果您想使用Fluent Syntax ,我相信以下方法会起作用(尽管我已经有一段时间没有使用它了):
modelBuilder.Entity<Agreement>()
.HasOne(x => x.ByerAgreementInfo)
.WithOne()
.HasForeignKey<Agreement>(p => p.ByerAgreementInfoId);
modelBuilder.Entity<Agreement>()
.HasOne(x => x.SellerAgreementInfo)
.WithOne()
.HasForeignKey<Agreement>(p => p.SellerAgreementInfoId);
注意:我认为您可能需要模型中的实际 Id,但我不记得了。
...但这会导致循环依赖
是的! 它会。 要克服这个问题,您必须指定.OnDelete(DeleteBehavior.Restrict);
在您的Fluent API配置中,如下所示,但首先您也必须按如下方式编写您的Agreement
模型类:
public class Agreement
{
public int Id { get; set; }
public Guid? BuyerId { get; set; }
public Guid? SellerId { get; set; }
public int AgreementIdForBuyer { get; set; }
public Guid OwnerActorIdForBuyer { get; set; }
public int AgreementIdForSeller { get; set; }
public Guid OwnerActorIdForSeller { get; set; }
public AgreementInfo ByerAgreementInfo { get; set; }
public AgreementInfo SellerAgreementInfo { get; set; }
}
现在在Fluent API配置中:
modelBuilder.Entity<Agreement>()
.HasOne(x => x.ByerAgreementInfo)
.WithOne()
.HasForeignKey<Agreement>(p => new {p.AgreementIdForBuyer, p.AgreementIdForBuyer})
.OnDelete(DeleteBehavior.Restrict); // <-- Here it is
modelBuilder.Entity<Agreement>()
.HasOne(x => x.SellerAgreementInfo)
.WithOne()
.HasForeignKey<Agreement>(p => new {p.AgreementIdForSeller, p.OwnerActorIdForSeller})
.OnDelete(DeleteBehavior.Restrict); // <-- Here it is
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.