2015-12-11 75 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是更容易管理。性能很好,数据完整性也很好。