我正在从.Net 2.1迁移到3.1,这包括EF Core升级。
现在我有了如下的LINQ查询,该查询没有任何问题:
var application = await _db.CustomerApplications
.AsNoTracking()
.Include(i => i.CustomerApplicationFields)
.Include(i => i.Customer)
.Where(x => x.Customer.PublicId == formId && x.IsPublished) // Also tried with &
.OrderByDescending(o => o.Version)
.FirstOrDefaultAsync();
使用EF Core 3.1时出现错误:
The LINQ expression 'DbSet<CustomerApplication>
.Where(c => !(c.Deleted))
.Join(
outer: DbSet<Customer>
.Where(c0 => !(c0.Deleted)),
inner: c => EF.Property<Nullable<long>>(c, "CustomerId"),
outerKeySelector: c0 => EF.Property<Nullable<long>>(c0, "Id"),
innerKeySelector: (o, i) => new TransparentIdentifier<CustomerApplication, Customer>(
Outer = o,
Inner = i
))
.Where(c => c.Inner.PublicId == __formId_0 && c.Outer.IsPublished)' 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(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
当我按以下方式转换此查询时,它就会起作用(将bool
评估移到外面):
var application = await _db.CustomerApplications
.AsNoTracking()
.Include(i => i.CustomerApplicationFields)
.Include(i => i.Customer)
.Where(x => x.Customer.PublicId == formId)
.OrderByDescending(o => o.Version)
.ToListAsync();
var result = application.FirstOrDefault(x => x.IsPublished);
有人可以向我解释为什么这是一个问题吗?我还尝试了x.IsPublished == true
,但没有任何效果。这似乎是随机的。
我还尝试了AsTracking()
。
答案 0 :(得分:2)
在EF Core 3.0之前,无法在客户端转换为SQL查询的查询。现在,此行为已被消除,并且引发了异常,而不是在客户端上评估不可翻译的查询。
我还认为,当您分别编写 var result = application.FirstOrDefault(x => x.IsPublished); 时,新行为不应导致任何重大性能问题,因为同一件事之前发生过。以前不可见。 (如果这个假设是错误的,请纠正我!)
如果您要进行一个查询(未对此进行测试),也可以尝试以下方法:
var application = await _db.CustomerApplications
.AsNoTracking()
.Include(i => i.CustomerApplicationFields)
.Include(i => i.Customer)
.Where(x => x.Customer.PublicId == formId)
.OrderByDescending(o => o.Version)
.FirstOrDefaultAsync(x => x.IsPublished);
答案 1 :(得分:0)
您应该使用&&代替&,或者可以添加另一个where子句。