Ответ 1
Вы можете попробовать это следующим образом:
var persons = Context.Persons
.OfType<Employee>()
.Include("Compensation")
.Concat<Person>(Context.Persons.OfType<Visitor>());
У меня есть классы вроде:
Person
{
Name
Address
}
Employee : Person
{
Compensation - object
}
Visitor : Person
{
}
Если я напишу linq:
var persons = Context.Persons
.Include("Compensation");
Я получаю ошибку:
Указанный путь Include недействителен. 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
но это не похоже, что это будет сделано в ближайшее время.
Каков хороший способ обхода проблемы?
Вы можете попробовать это следующим образом:
var persons = Context.Persons
.OfType<Employee>()
.Include("Compensation")
.Concat<Person>(Context.Persons.OfType<Visitor>());
Вот хороший пример загрузки 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-ответе
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);
Эта ужасная вещь работает:
var persons = context.Persons
.Concat(context.Employees
.Where(e => e.Compensation.Amount >= 0))
.Concat(context.Visitors
.Where(v => v.SomeProperty == "AlwaysTrue"));
Я не уверен, почему, но когда вы фильтруете свойство объекта, объект свойства загружается. Если вы не хотите фильтровать это свойство, используйте условие, которое всегда будет истинным.
Отказ от ответственности: я не знаю, насколько эффективен результирующий запрос. Я проверил sql, сгенерированный, когда тестировал это в несколько более сложном сценарии, и он был очень большим.