簡體   English   中英

EntityFramework代碼優先繼承,並渴望在派生類上包含關系

[英]EntityFramework code-first inheritance with eager include relationship on derived class

我認為使用TPH或TPT繼承方法不會對此產生影響。

我的目標是要有一個單一的方法,可以使用混合類型的實體從數據庫中加載所有內容,這些類型的實體可能具有不同的關系,具體取決於類型。

讓我們采用以下代碼優先模型(簡化模型來表示我的問題):

public abstract class Entity
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public abstract class EntityWithInfo : Entity
{
    public AdditionalInformation Info { get; set; }
}

public class DerivedEntityWithInfo : EntityWithInfo
{
}

public class DerivedEntityWithInfo2 : EntityWithInfo
{
}

public class DerivedEntityWithoutInfo : Entity
{
}

public class AdditionalInformation
{
    public int ID { get; set; }
    public int SomeProperty { get; set; }
}

以及Fluent API配置:

modelBuilder.Entity<Entity>()
    .HasKey(e => e.ID)
    .Map<DerivedEntityWithInfo>(m => m.Requires("Type").HasValue(1)
    .Map<DerivedEntityWithInfo2>(m => m.Requires("Type").HasValue(2)
    .Map<DerivedEntityWithoutInfo>(m => m.Requires("Type").HasValue(3);

modelBuilder.Entity<EntityWithInfo>()
    .HasRequired(e => e.Info)
    .WithRequiredPrincipal()
    .Map(e => e.MapKey("Entity_FK"));

modelBuilder.Entity<AdditionalInformation>()
    .HasKey(e => e.ID);

或視覺上: 視覺

SQL模式很簡單:

Table Entity with: Id, Type, Name
Table AdditionalInformation with: Id, SomeProperty, Entity_FK

現在,我希望能夠執行以下操作:

context.Entity.Where(t => t.ID = 304 || t.ID = 512).ToList();

這給了我正確的所有實體的列表,並正確鍵入了。 但是,當然Info屬性始終為null。 禁用LazyLoading並刪除虛擬也不會強制加載它,據我所知,我絕對需要在其中包含.Include(t => t.Info)行。

我知道我可以打電話

context.Entity.OfType<EntityWithInfo>().Include(t => t.Info).Where(t => t.ID = 304 || t.ID = 512).ToList();

但是,我只會得到從EntityWithInfo派生的實體,而不是DerivedEntityWithoutInfo的派生實體。

因此,讓我們嘗試一個聯合:

context.Entity.OfType<EntityWithInfo>().Include(t => t.Info).Cast<Entity>()
    .Union(context.Entity.OfType<DerivedEntityWithoutInfo>().Cast<Entity>())
    .Where(t => t.ID == 719 || t.ID == 402);

這不起作用,它告訴我“實體未聲明導航屬性Info”。

而且,我猜想這將創建一個SQL查詢的地獄。

實際上,我之所以這樣做,是因為一個非常老的項目正在使用LINQ2SQL,它與“ LoadWith”選項等效,生成了一個濫用SQL查詢(在每個繼承類型的聯接中復制關系表)。 加載單個實體所花的時間要比加載不帶層次結構的原始成千上萬個元素的整個表要多。 因此,我試圖查看是否移植到EntityFramework會生成更好的SQL查詢。

那么,有沒有辦法做到這一點,或者我們只是試圖以錯誤的方式做某事? 繼承,在派生類上的關系以及渴望加載這兩種方法似乎都不是一種很流行的方法,因為我幾乎沒有在線資源。

在這一點上,關於如何從該數據庫模型創建該對象模型的任何建議將不勝感激。 謝謝

EF Core 2.1現在支持此功能。 現在來看一下查詢結果是否不是很耗性能。

暫無
暫無

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

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