Использование .Net Core 2.1 и EF Core 2.1.1 и SQL Server
Я пытаюсь получить список Organizations
и их список Communications
Затем я хочу ограничить егодля тех, у кого не было Communications
за последние 6 месяцев
Вот мои уменьшенные ViewModels:
public class OrganizationViewModel
{
public Guid Id { get; set; }
public IEnumerable<CommunicationViewModel> CommunicationViewModels { get; set;
}
public class CommunicationViewModel
{
public Guid Id { get; set; }
public DateTime Date { get; set; }
public Guid OrganizationViewModelId { get; set; }
public OrganizationViewModel OrganizationViewModel { get; set; }
}
А вот мой запрос:
DateTime sixMonthsAgo = DateTime.Today.AddMonths(-6);
int pageIndex = 1; // Would be passed in
int pageSize = 3;
IQueryable<OrganizationViewModel> query = _context.Organizations
.AsNoTracking()
.Select(organization => new OrganizationViewModel
{
CommunicationViewModels = organization.Communications.Select(communication => new CommunicationViewModel
{
Date = communication.Date
})
.OrderByDescending(communication => communication.Date)
.Take(1)
.ToList()
})
.Where(organization =>
(!searchViewModel.LimitToLastSixMonths ||
organization.CommunicationViewModels.Any(communication => communication.Date <= sixMonthsAgo)));
int totalAmount = await query.CountAsync();
List<OrganizationViewModel> items = await query
.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
Это дает мне ожидаемые результаты, но я вижу в своих журналах, что я выполняю этот запрос для каждой записи, когда нажимаю .CountAsync()
и. Skip(..).Take(..)
:
SELECT CASE
WHEN EXISTS (
SELECT 1
FROM (
SELECT TOP(1) [comm].[Date]
FROM [Communications] AS [comm]
WHERE @_outer_Id = [comm].[OrganizationId]
ORDER BY [comm].[Date] DESC
) AS [t]
WHERE [t].[Date] <= @__sixMonthsAgo_0)
THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END
Ятакже видит эти предупреждения при вызове .CountAsync()
(слегка отредактированный):
Microsoft.EntityFrameworkCore.Query: Предупреждение: выражение LINQ
'where (False OrElse {from CommunicationViewModel cvm in {from Communication comm in value(..EntityQueryable'1[..Models.Communication]) orderby [comm].Date desc where ?= (Property([o], "Id") == Property([comm], "OrganizationId")) =? select new CommunicationViewModel() {Date = [comm].Date} => Take(1) => AsQueryable()} where ([cvm].Date <= __sixMonthsAgo_0) select [cvm] => Any()})'
не может быть переведено и будет оценено локально.
Microsoft.EntityFrameworkCore.Query: Предупреждение: выражение LINQ 'Count ()' не может быть переведено и будет оценено локально.
И подобные ошибки при вызове .Take(..).Skip(..)
:
Microsoft.EntityFrameworkCore.Query: Предупреждение: выражение LINQ
same as above
не может быть переведено и будет оцениваться локально.Microsoft.EntityFrameworkCore.Query: Предупреждение: выражение LINQ «Пропустить (__ p_1)» не может быть переведено и будет оценено локально.
Microsoft.EntityFrameworkCore.Query: Предупреждение: выражение LINQ «Take (__ p_2)» не может бытьпереведен и будет оцениваться локально.
Этого не происходит, если searchViewModel.LimitToLastSixMonths
ложно
Любые предложения о том, как я могу переписать свой запрос, чтобы не выполнять этот запрос локально для каждой записи