我正在使用.NET Core7和AutoMapper 12,并try 创建从实体框架查询到DTO列表的映射.

var configuration = new MapperConfiguration(cfg =>
{
    cfg.CreateProjection<MachineSchedule, MachineScheduleDataDto>()
        .ForMember(m => m.ShiftsDto, opts => opts.MapFrom(m => AddShiftCondition(m.Shifts, shiftType.Value))) // HERE
        .ForMember(m => m.ScheduledStopsDto, opts => opts.MapFrom(m => m.ScheduledStops))
        .ForMember(m => m.MachineOperationsDto, opts => opts.MapFrom(m => m.MachineOperations));

    cfg.CreateProjection<MachineOperation, MachineOperationDto>()
        .ForMember(m => m.EggQuantitiesDto, opts => opts.MapFrom(m => m.EggQuantities));

    cfg.CreateProjection<EggQuantity, EggQuantityDto>();

    cfg.CreateProjection<Shift, ShiftDto>();

    cfg.CreateProjection<ScheduledStop, ScheduledStopDto>();
});

var queryMapper = configuration.CreateMapper();

var diffDays = GetWeekdaysBetweenDates(startDate, endDate);

var test = queryMapper.ProjectTo<MachineScheduleDataDto>(_typedContext?
        .AsNoTracking()
        .Include(m => m.Shifts)
        .Include(m => m.ScheduledStops)
        .Include(m => m.MachineOperations)!
        .ThenInclude(m => m.EggQuantities)
    .OrderBy(m => m.MachineScheduleId));

正如你所看到的,我有方法AddShiftCondition:

private static IEnumerable<Shift>? AddShiftCondition(ICollection<Shift>? shifts, EShiftType? shiftType)
{
    if (shifts != null && !shifts.Any())
        return null;

    if (shiftType.HasValue)
        return shifts!.Where(s => s.Type == shiftType.Value);

    return shifts;
}

我不知道为什么,但如果我使用.ProjectTo(),AddShiftCondition就不会被调用,但如果我使用.Map(),一切都很好:

var configuration = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<MachineSchedule, MachineScheduleDataDto>()
        .ForMember(m => m.ShiftsDto, opts => opts.MapFrom(m => AddShiftCondition(m.Shifts, shiftType.Value)))
        .ForMember(m => m.ScheduledStopsDto, opts => opts.MapFrom(m => m.ScheduledStops))
        .ForMember(m => m.MachineOperationsDto, opts => opts.MapFrom(m => m.MachineOperations));

    cfg.CreateMap<MachineOperation, MachineOperationDto>()
        .ForMember(m => m.EggQuantitiesDto, opts => opts.MapFrom(m => m.EggQuantities));

    cfg.CreateMap<EggQuantity, EggQuantityDto>();

    cfg.CreateMap<Shift, ShiftDto>();

    cfg.CreateMap<ScheduledStop, ScheduledStopDto>();
});

var queryMapper = configuration.CreateMapper();

var diffDays = GetWeekdaysBetweenDates(startDate, endDate);

var test = queryMapper.Map<MachineScheduleDataDto>(_typedContext?
        .AsNoTracking()
        .Include(m => m.Shifts)
        .Include(m => m.ScheduledStops)
        .Include(m => m.MachineOperations)!
        .ThenInclude(m => m.EggQuantities)
    .FirstOrDefault());

为什么会发生这种事呢?

推荐答案

最简单的方法是直接丢弃该方法并直接编写表达式:

cfg.CreateProjection<MachineSchedule, MachineScheduleDataDto>()
    .ForMember(m => m.ShiftsDto, 
        opts => opts.MapFrom(m => m.Shifts.Where(s => s.Type == shiftType.Value))) // add empty collection handling if needed, though I would keep it simple

ProjectToIQueryable一起工作,对于ORM(如EF Core),它将导致LINQ查询转换为实际的SQL查询,并且不可能(在一般情况下)使用任意方法.所以AutoMapper似乎忽略了这个调用(尽管我希望翻译失败).

阅读更多内容:

.net相关问答推荐

.NET发布的应用程序运行与开发不同的端口

使用托管身份而不是检测密钥配置Application Insights

.NET 中两个子字符串之间的非贪婪正则表达式匹配

简单委托(委托)与多播委托

如何根据新的安全策略在 .Net 中发送邮箱?

如何使用 log4net 记录跟踪消息?

为什么 WCF 中不允许方法重载?

ASP.NET Core 等效于 ASP.NET MVC 5 的 HttpException

C#:获得完整的桌面大小?

将属性序列化为元素中的 Xml 属性

向 .NET 应用程序添加脚本功能

.NET 的 String.Normalize 有什么作用?

.NET 进程间通信的最佳 Select 是什么?

无法加载文件或程序集Antlr3.Runtime (1)或其依赖项之一

使用 lambda 表达式代替 IComparer 参数

接口属性的 XML 序列化

.NET Remoting 真的被弃用了吗?

您可以将 Microsoft Entity Framework 与 Oracle 一起使用吗?

从不同程序集中的类名中解析类型

捕获控制台退出 C#