【问题标题】:EF Core 3.1 Client Side Evaluation Issue With Boolean Async Call带有布尔异步调用的 EF Core 3.1 客户端评估问题
【发布时间】:2020-03-26 14:34:13
【问题描述】:

我正在从 .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()

【问题讨论】:

  • 你试过用 && 代替 & 吗?
  • 我都试过了
  • 什么是IsPublished?这是一个存储的属性还是计算出来的东西(例如IsPublished =&gt; PublishDate &gt; DateTime.UtcNow)?
  • 计算为是[NotMapped] public bool IsPublished =&gt; PublishDate.HasValue;。如果我直接使用PublishDate.HasValue,它就可以工作......有解决方法还是我需要使用直接评估?
  • EF Core 3.0 发行说明中直接提到了这个问题。你为什么不读它们?

标签: c# .net-core entity-framework-core-3.1


【解决方案1】:

在 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);

你可以在这里详细阅读:https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes#linq-queries-are-no-longer-evaluated-on-the-client

【讨论】:

  • 感谢您的回答和解释。
【解决方案2】:

你应该使用 && 而不是 & 或者你可以添加另一个 where 子句。

【讨论】:

  • 我更新了我的问题,我错过了一个&amp;。默认情况下我使用&amp;&amp;
猜你喜欢
  • 2020-05-02
  • 1970-01-01
  • 1970-01-01
  • 2020-02-01
  • 2016-04-24
  • 2020-12-02
  • 2020-10-08
  • 1970-01-01
  • 2015-08-22
相关资源
最近更新 更多