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

AutoMapper搭配EF Core查询嵌套属性等于指定值报错如何解决

问题根因

异常由两层类型不匹配冲突导致:

  1. 实体类ParentThing的ChildThingId为可空类型int?,对应的导航属性Child允许为null,但DTO层ChildDTO.Id声明为不可空int、ParentDTO.Child也未声明为可空,AutoMapper将e.Child.Id == id的DTO属性访问表达式转换为SQL可识别的实体表达式时,出现可空与不可空类型的匹配错误。
  2. 手动将id转为int?后,AutoMapper内部的表达式重写逻辑不允许隐式修改已声明成员的类型,因此抛出重写禁止异常。

解决方案

不需要扁平化嵌套属性,可任选以下一种方案解决:

方案1(最推荐):将过滤逻辑放在投影之前执行

直接针对EF原生实体做过滤,不存在表达式转换的兼容问题,查询性能最优:

var dtos = dbSet
    .Where(p => p.Child.Id == id)
    .ProjectTo<ParentDTO>(mapper.ConfigurationProvider)
    .ToList();

方案2:调整DTO可空性与实体对齐

如果业务需要在投影后执行过滤,修改DTO定义匹配实体的可空规则即可:

public class ParentDTO
{
    public string Name { get; set; }
    public ChildDTO? Child { get; set; } // 和实体导航属性的可空性保持一致
}

如果业务逻辑能保证Child一定不为null,也可以在AutoMapper映射配置中显式声明,避免类型推断错误:

CreateMap<ParentThing, ParentDTO>()
    .ForMember(d => d.Child, opt => opt.MapFrom(s => s.Child!));

方案3:过滤时增加显式null检查

不修改现有定义的前提下,在投影后的过滤条件中先判断Child不为null即可:

var dtos = mapper.ProjectTo<ParentDTO>(dbSet)
    .Where(e => e.Child != null && e.Child.Id == id)
    .ToList();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 20:45:04