Стремление загрузить свойство производного класса с помощью Include - PullRequest
15 голосов
/ 07 июня 2011

У меня есть такие классы, как:

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

но не похоже, что это будет сделано в ближайшее время.

Что является хорошим решением для этой проблемы?

Ответы [ 4 ]

7 голосов
/ 07 июня 2011

Вы можете попробовать это так:

var persons = Context.Persons
                     .OfType<Employee>()
                     .Include("Compensation")
                     .Concat<Person>(Context.Persons.OfType<Visitor>());
3 голосов
/ 11 декабря 2015

Вот хороший пример того, как загрузить 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 ответа

2 голосов
/ 18 февраля 2016
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);
0 голосов
/ 27 июля 2013

Эта ужасная вещь работает:

var persons = context.Persons
                .Concat(context.Employees
                    .Where(e => e.Compensation.Amount >= 0))
                .Concat(context.Visitors
                    .Where(v => v.SomeProperty == "AlwaysTrue"));

Я не уверен почему, но когда вы фильтруете свойство объекта, объект свойства загружается с нетерпением.Если вы не хотите фильтровать это свойство, используйте условие, которое всегда будет истинным.

Отказ от ответственности: я понятия не имею, насколько эффективен результирующий запрос.Я проверил SQL, сгенерированный, когда я тестировал это в немного более сложном сценарии, и он был очень очень большим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...