Entity Framework Core 查询仅适用于 .ToList()

问题描述 投票:0回答:1

我正在使用 .NET Core 7Entity Framework Core 7.0.13,我有以下查询:

var test = _context.Set<T>
    .AsNoTracking()
    .Include(m => m.MachineOperations!
        .Where(m =>
            m.InsertedAt.Date <= endDate.Date &&
            m.EndTime <= endDate.TimeOfDay &&
            m.InsertedAt.Date >= startDate.Date &&
            m.StartTime >= startDate.TimeOfDay))
    .ThenInclude(m => m.EggQuantities)
    .Where(m =>
        diffDays.Contains(m.WeekDay) &&
        m.MachineOperations!.Any() &&
        m.InitialProductionTime <= startDate.TimeOfDay &&
        m.FinalProductionTime >= startDate.TimeOfDay);

var test2 = _mapper.ProjectTo<MachineScheduleDataDto>(test);

我的问题是

.Where
条款没有被应用。经过一番尝试,我意识到,如果我在查询末尾添加
.ToList()
并使用
.AsQueryable()
转换它并作为参数传递给映射器后,
.Where
子句就可以正常工作。为什么会发生这种情况?我无法使用
.ToList()
,因为它选择了我正在查询的类的所有属性。

经过多次尝试,我意识到我的查询没问题,我的问题出在 .ProjectTo() 内部。 例如,如果我传递一些不应返回任何 MachineOperation 的参数,则查询实际上不会返回任何内容,这没关系,但是当查询结果通过

.ProjectTo
时,它会神奇地找到一些记录并把它带给我。这对我来说真的没有任何意义。

查询结果:

.ProjectTo() 的结果:

MachineScheduleDataDto 类:

public record MachineScheduleDataDto
{
    public required ICollection<MachineOperationDto> MachineOperationsDto { get; set; }
}

public record MachineOperationDto
{
    public int MachineOperationId { get; set; }
    public EMachineStatus MachineStatus { get; set; }

    public virtual required MachineScheduleDataDto MachineScheduleDto { get; set; }
}

我的地图绘制者:

CreateMap<MachineSchedule, MachineScheduleDataDto>()
    .ForMember(p => p.MachineOperationsDto, opts => opts.MapFrom(m => m.MachineOperations));

CreateMap<MachineOperation, MachineOperationDto>()
   .ForMember(p => p.MachineScheduleDto, opts => opts.MapFrom(m => m.MachineSchedule));
c# .net-core entity-framework-core iqueryable
1个回答
0
投票

鉴于这是 Automapper,尽管我不熟悉

ProjectTo
的风格,问题是您将急切加载/w 过滤与
IQueryable
投影混合在一起。投影 /w
ProjectTo
不需要,并且可能会忽略急切加载(包括过滤)。如果您想过滤投影,请通过映射配置来完成。因此,如果您有一个包含 MachineOperationDtos 的 MachineScheduleDataDto,则用于构建 MachineScheduleDataDto 的映射应包含有关要包含哪些 MachineOperations 的规则。即:

var configuration = new AutomapperConfiguration(cfg =>
{
    cfg.CreateMap<MachineScheduleData, MachineScheduleDataDto>()
        .ForMember(x => x.MachineOperationsDtos, 
            opt => opt.MapFrom(src => src.MachineOperations
               .Where(m =>
                  m.InsertedAt.Date <= endDate.Date &&
                  m.EndTime <= endDate.TimeOfDay &&
                  m.InsertedAt.Date >= startDate.Date &&
                  m.StartTime >= startDate.TimeOfDay)));
});

该配置显然也具有 MachineOperation -> MachineOperationDto 等的映射,并将使用这些映射将过滤后的机器操作结果映射到其 DTO 中。那么你的查询结果将如下所示:

var query= _context.Set<MachineScheduleDatas>
    .Where(m =>
        diffDays.Contains(m.WeekDay) &&
        m.MachineOperations!.Any() &&
        m.InitialProductionTime <= startDate.TimeOfDay &&
        m.FinalProductionTime >= startDate.TimeOfDay);

var dtos = await_mapper.ProjectTo<MachineScheduleDataDto>(query)
    .ToListAsync();

或者我更熟悉的:

var dtops = await _context.Set<MachineScheduleDatas>
    .Where(m =>
        diffDays.Contains(m.WeekDay) &&
        m.MachineOperations!.Any() &&
        m.InitialProductionTime <= startDate.TimeOfDay &&
        m.FinalProductionTime >= startDate.TimeOfDay)
    .ProjectTo<MachineScheduleDataDto>(configuration)
    .ToListAsync();
© www.soinside.com 2019 - 2024. All rights reserved.