【发布时间】:2018-09-28 16:53:38
【问题描述】:
使用 .Net Core 2.1 和 EF Core 2.1.1 和 SQL Server
我正在尝试提取Organizations 的列表及其Communications 的列表
然后,我想将其限制在过去 6 个月内没有任何 Communications 的用户
这是我略读的 ViewModel:
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:Warning:LINQ 表达式
same as above无法翻译,将在本地进行评估。 Microsoft.EntityFrameworkCore.Query:警告:无法翻译 LINQ 表达式“Skip(__p_1)”,将在本地进行评估。
Microsoft.EntityFrameworkCore.Query:警告:无法翻译 LINQ 表达式“Take(__p_2)”,将在本地进行评估。
searchViewModel.LimitToLastSixMonths 为假时不会发生这种情况
关于如何重写查询以不在每条记录上本地执行该查询的任何建议?
【问题讨论】:
标签: c# sql-server linq asp.net-core entity-framework-core