You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core应用LINQ表达式无法翻译错误的解决求助

问题原因与解决方案

问题根源

你遇到的错误是因为EF Core无法将「映射到DTO之后再过滤」的逻辑转换为SQL。当你先通过Select创建TicketSchedulerDTO对象,再用Where对DTO的属性进行过滤时,EF Core尝试把整个表达式翻译成SQL,但DTO是内存中的客户端对象,数据库无法识别这种针对DTO字段的过滤条件。本地测试能运行可能是因为启用了隐式客户端评估,而当前环境禁用了该特性(这是EF Core的默认行为,避免性能问题)。

修复方案

将所有过滤逻辑提前到Select之前,直接针对数据库视图TicketView的原生字段进行过滤,这样EF Core可以把过滤条件转换为SQL,在数据库层面完成筛选,既解决翻译问题,也提升查询效率。

修改后的代码示例

public async Task<List<TicketSchedulerDTO>> GetAssignedTickets(ScheduleFilterDTO dTO, List<string> BranchIdList)
{
    try
    {
        var query = context.TicketView
            .Where(x => BranchIdList.Contains(x.BranchId.ToString()))
            .Where(t => t.ScheduleDateTime <= dTO.EndDate && t.ScheduleDateTime >= dTO.StartDate && t.StatusId != 1 && t.StatusId != 7)
            // 把原Select后的过滤条件移到此处,直接使用TicketView的原生字段
            .Where(x => 
                (dTO.TicketCategoryIDs == null || !dTO.TicketCategoryIDs.Any() || dTO.TicketCategoryIDs.Contains(0) || dTO.TicketCategoryIDs.Contains(x.CategoryId)) &&
                (dTO.TicketStatusIDs == null || !dTO.TicketStatusIDs.Any() || dTO.TicketStatusIDs.Contains(0) || dTO.TicketStatusIDs.Contains(x.StatusId)) &&
                (dTO.WorkerIDs == null || !dTO.WorkerIDs.Any() || dTO.WorkerIDs.Contains(0) || dTO.WorkerIDs.Contains(x.WorkerId)) &&
                (dTO.LocationIDs == null || !dTO.LocationIDs.Any() || dTO.LocationIDs.Contains(0) || dTO.LocationIDs.Contains(x.LocationId)) &&
                (dTO.DepartmentIDs == null || !dTO.DepartmentIDs.Any() || dTO.DepartmentIDs.Contains(0) || dTO.DepartmentIDs.Contains(x.DepartmentId)) &&
                (dTO.SupervisorID == null || !dTO.SupervisorID.Any() || dTO.SupervisorID.Contains(0) || dTO.SupervisorID.Intersect(dTO.WorkerIDs).Any())
            )
            .Select(x => new TicketSchedulerDTO
            {
                Id = x.Id,
                CallDateTime = x.CallDateTime,
                Start = x.ScheduleDateTime,
                CompleteDateTime = x.CompleteDateTime,
                TotalEstimate = x.TotalEstimate,
                End = GetEndFromEstimate(x.ScheduleDateTime, x.TotalEstimate, dTO.WorkDayEnd),
                Title = MOM.Alias.Common.DTO.TicketID + " " + x.Id,
                Description = x.Reason,
                Address = x.Address,
                City = x.City,
                StateName = x.StateName,
                CountryName = x.CountryName,
                WorkerId = x.WorkerId,
                WorkerName = (x.WorkerId == null) ? MOM.Alias.Common.DTO.UnassignedTicket : x.WorkerName,
                CategoryName = x.CategoryName,
                LocationName = x.LocationName,
                Equipment = x.Equipment,
                StatusId = x.StatusId,
                StatusName = x.StatusName,
                StatusColor = x.StatusColor,
                Longitude = x.Longitude,
                Latitude = x.Latitude,
                BranchName = x.BranchName,
                CreatedBy = x.CreatedBy,
                WorkComplete = x.WorkComplete,
                EnteredBy = x.EnteredBy,
                IsCharge = x.IsCharge,
                IsDocument = x.IsDocumentExist,
                DispatchAlert = x.DispatchAlert,
                IsSignature = x.IsSigned,
                IsReviewed = x.IsReviewed,
                IsTimesheet = x.IsTimesheet,
                InvoiceId = x.InvoiceId,
                RecurringDate = x.RecurringDate,
                OverTime = x.OverTime,
                IsPayroll = x.IsPayroll,
                Icon = context.TicketCategory.Where(y => y.Id == x.CategoryId).Select(y => y.Icon).FirstOrDefault(),
            });

        return await query.ToListAsync();
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

关键改动说明

  • 移除了Select之后的Where,将所有过滤条件移到Select之前,直接使用TicketView的字段(比如x.CategoryId代替原来的y.CategoryId)。
  • 简化了过滤条件中的冗余判断(比如Count() == 0和!Any()重复,保留!Any()即可)。
  • 确保所有过滤逻辑都能被EF Core转换为SQL语句,在数据库端执行筛选。

内容的提问来源于stack exchange,提问作者Prashil Shah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 08:04:51