簡體   English   中英

具有單獨ID屬性的EF6一對一關系

[英]EF6 One-To-One relationship with separate ID property

我們需要在以下實體之間定義一對一關系:

public class Foo
{
    [Key, Column("Foo_ID")]
    public int Id { get; set; }

    public Bar Bar { get; set; }
}

public class Bar
{
    [Key, Column("Bar_ID")]
    public int Id { get; set; }

    [Column("Bar_Foo_ID")]
    public int? FooId { get; set; }

    public Foo Foo { get; set; }   
}

我們需要遷移舊版軟件,並讓它們現在並排運行。 所以我們不能改變任何關系。 遺憾的是,數據庫中沒有定義外鍵。

modelBuilder.Entity<Foo>()
            .HasOptional(a => a.Bar)
            .WithRequired(x => x.Foo)
            .WillCascadeOnDelete(true);

當我們查詢FooInclude(x => x.Bar)它會創建一個帶有LEFT OUTER JOIN bars ON Foo_ID = Bar_ID的SQL查詢LEFT OUTER JOIN bars ON Foo_ID = Bar_ID這是錯誤的。

我們需要LEFT OUTER JOIN bars on Foo_ID = Bar_Foo_ID其更改為LEFT OUTER JOIN bars on Foo_ID = Bar_Foo_ID ,但我不確定Entity Framework是如何支持的,因為我們的DB和Bar_ID沒有外鍵作為PrimaryKey。

我知道一個Foo可能有多個Bars ,但是有沒有辦法強制實現一對一關系?

創建Foo ,始終會為其創建一個Bar

對於舊數據,您可以使用以下內容:

1:0-1關系基本上是1:許多關系的特殊形式。

因此,您可以在實體框架中將關系配置為1:many,並可能向外鍵屬性添加唯一索引,以強制執行max的約束。 一個相關的條目。

public class Foo
{
    [Key, Column("Foo_ID")]
    public int Id { get; set; }

    // this can't be a single reference property unfortunately... but it will only contain 0 or 1 object when working with it.
    public ICollection<Bar> Bars { get; set; }
}

public class Bar
{
    [Key, Column("Bar_ID")]
    public int Id { get; set; }

    [Index(IsUnique = true)]
    [Column("Bar_Foo_ID")]
    public int? FooId { get; set; }

    public Foo Foo { get; set; }   
}

modelBuilder.Entity<Foo>()
            .HasMany(a => a.Bars)
            .WithRequired(x => x.Foo)
            .HasForeignKey(x => x.FooId)
            .WillCascadeOnDelete(true);

我理解它的方式,你在Bar表中有一個名為Bar_Foo_ID的現有列,它必須用作Bar表中PK Bar_ID列的FK。

這是可能的,但EF6對這種關系的支持有限,特別是不支持顯式FK屬性。 所以你必須從模型中刪除FooId屬性:

public class Bar
{
    [Key, Column("Bar_ID")]
    public int Id { get; set; }

    public Foo Foo { get; set; }   
}

並使用以下流暢的配置:

modelBuilder.Entity<Foo>()
    .HasOptional(a => a.Bar)
    .WithOptionalPrincipal(x => x.Foo)
    .Map(m => m.MapKey("Bar_Foo_ID"))
    .WillCascadeOnDelete(true);

MapKey是指定FK列名。 WithOptionalPrincipal用於指定它可以為空(而WithRequired用於非可空)。

請注意,對於可選關系,EF6會以不同方式處理級聯刪除。 它不是刪除相關記錄,而是通過將FK設置為null來取消它們。 如果您想在刪除Foo時實際刪除關聯的Bar ,則必須使用代碼手動執行此操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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