1

我们有一个使用传统ADO.NET技术成功运行的大型企业应用程序。我们正在用EF 6进行试验,看看我们是否可以减少一些传统技术所需的管道(请不要回答任何这些问题的优点和缺点,我们已经完成了功课)。EntityFramework代码优先和自定义继承

我们决定使用EF Code First方法,因为它与我们现有的代码凝胶最好。我们坚持在EF模型类中表示特定的继承方案。

有一个名为Profiles的表,它具有ProfileId(Identity)和ProfileNumber列。基本的细节有点复杂,但为了试用简单的话来说,ProfileId是一个主键。 ProfileNumber可以是唯一的或不基于配置文件的类型。例如对于代理配置文件,ProfileNumber不能在“配置文件”表中重复。

现在有另一个名为AgentDetails的表,它具有ProfileNumber作为到Profiles表的外键(AgentDetails表中没有ProfileId列)。请不要提出架构更改,这对于我们的部署方式根本不可行。

现在我们已经在我们的代码中创建了一个具有所有属性的Profile类。我们创建了另一个名为Agent的类,它来自Profile。它具有除ProfileNumber之外的AgentDetails表中所有列的属性,因为它是从Profile类继承的。

我们正在尝试编写一个LINQ查询,该查询返回代理对象,其中还填充了所有Profile类派生属性。然而,在尝试了各种LINQ查询(有和没有显式连接)之后,似乎都没有成功。我们总是在ProfileId列上得到一个错误,它指示来自LINQ查询的结果集不包含ProfileId列。

是否有可能在这种情况下使用DbContext和DbSet和Linq查询来编写一个LINQ表达式,该表达式在ProfileNumber上连接AgentDetails和Profiles表,并返回一个代理对象列表,其中也填充了基础配置文件属性。

我们尝试过使用各种DataAnnotation属性(但未查看Fluent API)来完成此操作,但尚未成功。

请注意,我们不等待代理对象包含Profile对象,我们希望它从Profile继承。 This blog post在数据库中明确定义关系时表现出相同的效果。在我们的例子中,AgentDetails和Profiles表之间没有数据库中定义的外键关系。

Off-course,一种方法是在这种情况下使用DataReader,并手动填充对象属性。我们试图看看是否有一种原生的EF方法来完成此项工作,否则我们可能会考虑委托给好的旧数据读取器。

更新:这里是代码的镂空版本:

Table("Profiles")] 
public class Profile 
{ 
    public int ProfileId {get; set;} 
    public string ProfileNumber {get;set;} 
    public string FullName {get;set;} 
} 

Table("AgentDetails")] 
public class Agent : Profile 
{ 
    //Notice I omitted ProfileNumber column, that's present in AgentDetails in database, but inherited from Profile class here. 
    public decimal CommissionPct {get;set;} 
} 

下面是一个示例查询:

//Basically trying to get a list of all agents 
this.context.Agents.ToList(); 

而我们得到的错误是:

无效列简档

+1

请分享一些代码,如LINQ查询,异常细节,轮廓和代理类的最低版本。 – jessehouwing

+0

嗨耶斯,我已经更新了更多的细节问题,谢谢你的时间。 –

+0

这是有道理的吧?您没有使用映射到表的继承,而是使用映射到多个表的继承。 (参见:http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-inheritance-with-the-entity-framework-in-an-asp -net-mvc-application)您将需要解释EF如何将AgentNeta参数从AgentDetails映射到Profile表,以便它可以构造整个实体。你需要告诉模型构建者你的意图。沿着这些路线的东西:http://stackoverflow.com/a/6850481/736079 – jessehouwing

回答

0

首先,您在配置文件实体中指定主键。 如果你只在DbContext中设置DbSet对于代理,这很好,并且正常工作。