我们有一个使用传统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();
而我们得到的错误是:
无效列简档
请分享一些代码,如LINQ查询,异常细节,轮廓和代理类的最低版本。 – jessehouwing
嗨耶斯,我已经更新了更多的细节问题,谢谢你的时间。 –
这是有道理的吧?您没有使用映射到表的继承,而是使用映射到多个表的继承。 (参见: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