Ошибка при фильтрации по включению в Entity Framework Core

У меня есть следующий оператор EF Core linq:

var contact = dataContext.Contacts
                    .Include(c => c.Addresses)
                        .ThenInclude(a => a.AddressType)
                    .Where(c => c.ContactId == contactId)
                    .Select(c => new Contact()
                    {
                        ContactId = c.ContactId,
                        Title = c.Title,
                        FirstName = c.FirstName,
                        Surname = c.Surname,
                        Addresses = c.Addresses.Where(a => a.IsPrimary)
                    })
                    .SingleOrDefault();

... который дает следующую ошибку при вызове:

Выражение типа «System.Collections.Generic.IEnumerable1[Microsoft.EntityFrameworkCore.Storage.ValueBuffer]' cannot be used for parameter of type 'System.Collections.Generic.IEnumerable1[TeenyCRM.DataModel.Address]» метода «System.Collections.Generic.IEnumerable1[TeenyCRM.DataModel.Address] _ToEnumerable[Address](System.Collections.Generic.IEnumerable1[TeenyCRM.DataModel.Address])»

Если поместить .ToList() в проекцию адресов, она выполняется без ошибок:

i.e.

var contact = dataContext.Contacts
                    .Include(c => c.Addresses)
                        .ThenInclude(a => a.AddressType)
                    .Where(c => c.ContactId == contactId)
                    .Select(c => new Contact()
                    {
                        ContactId = c.ContactId,
                        Title = c.Title,
                        FirstName = c.FirstName,
                        Surname = c.Surname,
                        Addresses = c.Addresses.Where(a => a.IsPrimary).ToList()
                    })
                    .SingleOrDefault();

Однако EF Core генерирует и выполняет 2 оператора SQL в фоновом режиме.

Есть ли способ заставить это работать, генерируя только один оператор SQL за кулисами?


person Carl Rippon    schedule 23.01.2018    source источник
comment
EF Core не использует одиночный SQL для запросов, включающих подколлекции. В лучшем случае он выполняет 1 + C SQL-запросов, где C — количество вложенных коллекций. В худшем случае, как здесь - 1 + N * C SQL-запросы. Вы ничего не можете с этим поделать. Последнее является ошибкой и будет исправлено, а первое (1 + C запросов) является преднамеренным.   -  person Ivan Stoev    schedule 23.01.2018