2015-12-11 113 views
1

我正在爲有一個航班表和ClubMembers表中的飛行俱樂部的數據庫上。不幸的是,必須支付航班費用,因此有一個BillTo引用了必須支付的俱樂部成員。繼承層次結構中的實體框架

到目前爲止,它看起來像這樣...

public ClubMember 
{ 
public int ID{get;set;} 
public string FirstName{get;set;} 
public string LastName {get;set;} 
} 
public Flight 
{ 
public int ID {get;set;} 
public ClubMember PilotPayingTheBill{get;set;} 
public double EnormousPriceToBePaid {get;set;} 
} 

很簡單......但隨後的混亂的世界進行干預。有時爲了維護目的,飛機由機械師飛行。我不想以這種懶惰的方式做到這一點,並在俱樂部成員表中輸入機械師作爲虛擬記錄。數據庫對於那種混合物來說太新了。此外,EF必須在數據庫中實現繼承漂亮的能力,所以我可以保持它的所有漂亮和整潔是這樣的:

public BillableEntity 
{ 
public int ID{get;set;} 
} 

ClubMember : BillableEntity 
{ 
public string FirstName{get;set;} 
public string LastName {get;set;} 
} 
NonPayingUser : BillableEntity 
{ 
public string Description {get;set;} 
} 
public Flight 
{ 
public int ID {get;set;} 
public BillableEntity billTo{get;set;} 
public double EnormousPriceToBePaid {get;set;} 
} 

在我流利的配置NonPayingUser和ClubMembers幾條指令都放在自己的表,ID爲主鍵和外鍵 - 一個很好,簡潔的設計,我非常滿意。航班表中的Billto_id列不爲空,因此每個航班總是有一個可結算的實體,它可以是俱樂部會員或NonPayingUser。

寫作TSQL查詢是很容易

select coalesce(cm.FirstName + ' ' + cm.LastName,np.Description) as BillTo 
from Flights f 
left outer join ClubMembers cm on f.billto_id = cm.ID 
left outer join NonPayingUsers np on f.billto_id = np.ID 

但這樣做在EF同樣的事情有我難住了。 Flight類有一個BillTO屬性,它是BillableEntity的父類。我可以將它投到像這樣的後代類...

 var flights = DB.Flights 
         .Select(f => new 
         { 
          PersonName = (f.BillTo as ClubMember).FirstName + PersonName = (f.BillTo as ClubMember).LastName 
              , 
          OtherName = (f.BillTo as NonPayingUser).Description 
         }); 

但這會產生可怕的數量的TSQL。

一個解決方案就是編寫我自己的存儲過程將這些表連接在一起,並使用EF類來完成各個表上的所有基本CRUD,這就是我所傾向的方向。但是有沒有更好的方法辦法?

+0

你使用什麼樣的繼承?每個層級表(TPH),每個表類型(TPT)還是每個具體表類別(TPC)? –

+0

每類型繼承的表 –

回答

0

這是幾個類似的問題重複...

EF(6,我期待在7 RC1現在)總是產生一個巨大的TSQL的量。

我認爲最好的答案是什麼,是的「生產滔天金額TSQL的」問題?
如果您在查詢時遇到特定問題,請解決該問題,否則請忽略它。你會發現,在很大比例的情況下,它不會導致數據庫管理系統的問題。

0

我結束了在BillableEntities表

alter table BillableEntities drop column name; 
    alter table BillableEntities add Name as (case when [Description] is null then LastName + ', ' + FirstName else [Description] end) 

創建一個計算的字段,然後在BIllableEntities類將其標記爲DataBaseGenerated。

[DatabaseGenerated(DatabaseGeneratedOption.Computed)] 
    public string FullName { get; private set; } 

這樣由EF生成的SQL是更容易管理。性能很好,數據完整性也很好。