Использование EF Core ThenInclude() на таблицах соединений
Я переношу свой код .NET Framework (EF6) в ядро ASP.NET(EF Core), и я наткнулся на эту проблему. Вот пример кода:
В EF6 я использую Include() и Select() для eager-loading:
return _context.Post
.Include(p => p.PostAuthor.Select(pa => pa.Author).Select(a => a.Interests))
PostAuthor - это таблица переходов, а также есть таблица соединений "AuthorInterest", которую мне не нужно было включать в EF6 (Select идет прямо на a.Interests).
В любом случае, я вижу, что в EF7 это переработано, что означает, что теперь я должен использовать ThenInclude() для вложенных запросов. Однако...
return _context.Post
.Include(p => p.PostAuthor)
.ThenInclude(pa => pa.Select(pa2 => pa2.Author))
...etc
Вышеприведенный код выходит из строя из-за оператора Select(). Документация на https://docs.efproject.net/en/latest/querying/related-data.html, кажется, предполагает, что мне она не нужна, и я могу получить доступ к автору сразу, но я получаю ICollection в последнем лямбда отображается, поэтому мне явно нужен Select(). Я прохожу через несколько таблиц соединений далее в запросе, но для простоты позвольте просто сосредоточиться на первом.
Как мне сделать эту работу?
Ответы
Ответ 1
но я получаю ICollection в последней отображаемой лямбда, поэтому мне явно нужен Select()
Нет, нет. EF Core Include
/ThenInclude
полностью заменит необходимость использования Select
/SelectMany
, используемого в EF6. Оба они имеют отдельные перегрузки для свойств навигации для сбора и ссылочного типа. Если вы используете перегрузку с коллекцией, ThenInclude
работает с типом коллекции element, поэтому в конце вы всегда получаете один тип сущности.
В вашем случае pa
должен быть разрешен к типу элемента таблицы соединений, поэтому Author
должен быть непосредственно доступен.
Например, EF6 включает цепочку:
.Include(p => p.PostAuthor.Select(pa => pa.Author).Select(a => a.Interests))
переводится в EF Core:
.Include(p => p.PostAuthor).ThenInclude(pa => pa.Author).ThenInclude(a => a.Interests)