У меня есть модель данных, где объект 'Top' имеет объекты от 0 до N 'Sub'. В SQL это достигается с помощью внешнего ключа dbo.Sub.TopId
.
var query = context.Top
//.Include(t => t.Sub) Doesn't seem to do anything
.Select(t => new {
prop1 = t.C1,
prop2 = t.Sub.Select(s => new {
prop21 = s.C3 //C3 is a column in the table 'Sub'
})
//.ToArray() results in N + 1 queries
});
var res = query.ToArray();
В Entity Framework 6 (с ленивой загрузкой) этот запрос Linq будет преобразован в запрос single SQL. Результат будет полностью загружен, поэтому res[0].prop2
будет IEnumerable<SomeAnonymousType>
, который уже заполнен.
При использовании EntityFrameworkCore (NuGet v1.1.0) однако подсекция еще не загружена и имеет тип:
System.Linq.Enumerable.WhereSelectEnumerableIterator<Microsoft.EntityFrameworkCore.Storage.ValueBuffer, <>f__AnonymousType1<string>>.
Данные не будут загружаться до тех пор, пока вы не перейдете к нему, в результате чего появятся N + 1 запросы. Когда я добавляю .ToArray()
к запросу (как показано в комментариях), данные полностью загружаются в var res
, используя профилировщик SQL, но показывает, что это больше не достигается в 1 запросе SQL. Для каждого объекта "Top" выполняется запрос в таблице "Sub".
Вначале указание .Include(t => t.Sub)
, похоже, ничего не меняет. Использование анонимных типов тоже не является проблемой, замена блоков new { ... }
на new MyPocoClass { ... }
ничего не меняет.
Мой вопрос: Есть ли способ получить поведение, подобное EF6, где все данные сразу загружаются?
Примечание. Я понимаю, что в этом примере проблему можно устранить, создав анонимные объекты в памяти после выполнения запроса следующим образом:
var query2 = context.Top
.Include(t => t.Sub)
.ToArray()
.Select(t => new //... select what is needed, fill anonymous types
Однако это всего лишь пример, мне действительно нужно создать объекты, которые будут частью запроса Linq, поскольку AutoMapper использует это для заполнения DTO в моем проекте
<ы > Обновление: Протестировано с новым EF Core 2.0, проблема сейчас. (21-08-2017)
Проблема отслеживается на aspnet/EntityFrameworkCore
GitHub repo: Проблема 4007
С >
Обновление: Год спустя эта проблема была исправлена в версии 2.1.0-preview1-final
, см. мой ответ ниже. (01-03-2018)