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

.NET升级至7+AutoMapper12时ProjectTo抛出'Default'类型LINQ异常

问题分析与解决方案

问题根源

升级到AutoMapper 12后,EF Core投影对可空导航属性的表达式生成逻辑发生了变化:

  • 原始自动映射时,当ProcessedBy为null,AutoMapper会生成default(ApplicationUserPreview)表达式,但EF Core无法解析这种Default类型的LINQ表达式,抛出Unknown LINQ expression of type 'Default'。
  • 使用DoNotAllowNull()时,若ApplicationUserPreview中存在非可空值类型属性(比如Guid Id而非Guid? Id),当数据库中ProcessedById为null时,EF尝试将null映射到非可空属性,就会触发cast to value type 'System.Guid' failed异常。

解决方案

方案1:修正DTO属性的可空性

检查ApplicationUserPreview的定义,确保所有从可空关联实体映射的属性都声明为可空类型:

public class ApplicationUserPreview
{
    // 将非可空Guid改为可空
    public Guid? Id { get; set; }
    // 其他可能为null的属性同理调整
    public string? UserName { get; set; }
}

之后使用AllowNull()配置映射:

CreateProjection<PaymentUpload, PaymentUploadDto>()
    .ForMember(dest => dest.ProcessedBy, opt => opt.AllowNull());

方案2:手动指定投影逻辑

通过MapFrom显式处理null情况,避免AutoMapper生成EF无法解析的默认表达式:

CreateProjection<PaymentUpload, PaymentUploadDto>()
    .ForMember(dest => dest.ProcessedBy, opt => opt.MapFrom(src => 
        src.ProcessedBy == null 
            ? null 
            : new ApplicationUserPreview
            {
                Id = src.ProcessedBy.Id,
                UserName = src.ProcessedBy.UserName,
                // 映射其他需要的属性
            }));

如果已经存在ApplicationUser到ApplicationUserPreview的映射配置,也可以结合ProjectTo复用:

CreateProjection<PaymentUpload, PaymentUploadDto>()
    .ForMember(dest => dest.ProcessedBy, opt => opt.MapFrom(src => 
        src.ProcessedBy == null 
            ? null 
            : src.ProcessedBy.ProjectTo<ApplicationUserPreview>(Mapper.ConfigurationProvider)));

方案3:启用AutoMapper兼容模式(临时方案)

如果暂时不想修改大量代码,可以尝试启用AutoMapper旧版兼容行为,在全局配置中添加:

cfg.UseNullSubstituteForValueTypes = true;

注意:该选项可能在后续版本被移除,建议优先采用前两种方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 07:52:47