簡體   English   中英

是否可以在沒有外鍵的情況下設置導航屬性?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM