【发布时间】:2020-12-28 04:27:39
【问题描述】:
首先,完整的场景可以在这里找到: https://dotnetfiddle.net/a2aIkJ
我正在使用 AutoMapper 对 DTO 属性启用过滤(LINQ 表达式)并将此表达式映射回数据库实体。在 AutoMapper 配置中,我有以下场景:
cfg.CreateMap<Car, CarDto>()
.ForMember(dest => dest.BrandFks, opt => opt.MapFrom(source => source.Wheels.Select(x => x.FkBrand)));
当我使用以下代码时,LINQ 到 SQL 的转换按预期工作:
// This code throws NO error
var working = context.Cars
.UseAsDataSource(mapper.ConfigurationProvider).For<CarDto>()
.Where(x => x.BrandFks.Any(y => y == 1))
.ToList();
但是,当我检查同一个属性是否为 null 时:
// This code throws the error
var notWorking = context.Cars
.UseAsDataSource(mapper.ConfigurationProvider).For<CarDto>()
.Where(x => x.BrandFks == null)
.ToList();
出现以下错误:
Unhandled exception. System.InvalidOperationException: The LINQ expression 'DbSet<Car>
.Where(c => DbSet<Wheel>
.Where(w => EF.Property<Nullable<int>>(c, "Id") != null && EF.Property<Nullable<int>>(c, "Id") == EF.Property<Nullable<int>>(w, "Id"))
.Select(w => w.FkBrand) == null)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync().
有人知道为什么这不起作用以及我如何解决这个问题吗?
编辑 - 澄清: 过滤器表达式由另一个只知道 DTO 而对数据库一无所知的组件定义。
【问题讨论】:
-
不是检查
null,你不应该使用!x.BrandFks.Any()吗?看来BrandFks是一个集合,可以没有成员,但不能为空...? -
@NetMage 但是检查
null仅在查看 DTO 时才有意义,在我的情况下,过滤器表达式是由只知道 DTO 的组件设置的,而对它的保存方式一无所知数据库 -
翻译显示查询仍在被翻译为 SQL,因此 DTO 不(完全)相关。你可以把
.AsEnumerable()放在Where前面,把所有涉及到的数据拉到客户端去测试?
标签: linq linq-to-sql entity-framework-core automapper ef-core-3.1