我有类似的课程:
Person
{
Name
Address
}
Employee : Person
{
Compensation - object
}
Visitor : Person
{
}
如果我写linq:
var persons = Context.Persons
.Include("Compensation");
我收到错误:
指定的包含路径无效。 EntityType'Person'没有 用。声明一个导航属性 名称'赔偿'。
如果我这样做,它就可以了:
var persons = Context.Persons
.OfType<Employee>()
.Include("Compensation");
但我想在同一个查询中找到员工和访客。
看起来EF4 UserVoice上有此功能的请求: http://data.uservoice.com/forums/72025-ado-net-entity-framework-ef-feature-suggestions/suggestions/1249289-include-property-of-derived-classes?ref=title
但它看起来不会很快就会完成。
这个问题有什么好的解决方法?
答案 0 :(得分:7)
你可以这样试试:
var persons = Context.Persons
.OfType<Employee>()
.Include("Compensation")
.Concat<Person>(Context.Persons.OfType<Visitor>());
答案 1 :(得分:3)
以下是如何为Persons
Compensation
并包含Employees
的一个很好的示例
将Reference()
替换为Collection()
以获取集合属性。
IQueryable<Person> GetPersons()
{
var persons = Context.Persons;
foreach(var entry in persons.OfType<Employee>())
Context.Entry(entry).Reference(e => e.Compensation).Load();
return persons;
}
不确定它是否有效,但是它有效,并且意图比连接更清晰。
基于此SO answer
答案 2 :(得分:2)
var employees = context.Persons.OfType<Employee>().Include(x => x.Compensation).ToArray();
var nonEmployees = context.Persons.Except(context.Persons.OfType<Employee>()).ToArray();
var people = employees.Concat(nonEmployees);
答案 3 :(得分:0)
这件可怕的事情有效:
var persons = context.Persons
.Concat(context.Employees
.Where(e => e.Compensation.Amount >= 0))
.Concat(context.Visitors
.Where(v => v.SomeProperty == "AlwaysTrue"));
我不知道为什么,但是当您过滤对象属性时,会急切地加载该属性的对象。如果您不想过滤该属性,请使用始终为真的条件。
免责声明:我不知道生成的查询效率如何。我检查了在一个稍微复杂的场景中测试时生成的sql,它非常非常大。