是否可以具有两个(或多个)相同类型的导航属性?
我的模特看起来像这样...
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列之外),允许我将信息表行用作协议类中的导航属性?
答案 0 :(得分:0)
有多种方法可以实现您想要的。您可以将数据注释与孩子的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语法,我相信以下内容会起作用(尽管我已经有一段时间没有使用它了)
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,尽管我不记得了
答案 1 :(得分:0)
...但是这导致了循环依赖
是的!它会。为了克服这个问题,您必须在 Fluent API 配置中指定.OnDelete(DeleteBehavior.Restrict);
,如下所示,但首先您也必须编写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