简体   繁体   English

带有布尔异步调用的 EF Core 3.1 客户端评估问题

[英]EF Core 3.1 Client Side Evaluation Issue With Boolean Async Call

I am migrating form .Net 2.1 to 3.1 and this is including EF Core upgrade.我正在从 .Net 2.1 迁移到 3.1,这包括 EF Core 升级。

Now I had LINQ query as following, that worked with no issues:现在我有如下 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();

With EF Core 3.1 I get error:使用 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.

When I convert this query as following, then it works (moving bool evaluation outside):当我按如下方式转换此查询时,它会起作用(将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);

Could someone explain to me, why this is an issue?有人可以向我解释一下,为什么这是一个问题? I also tried x.IsPublished == true , which had no effect.我也试过x.IsPublished == true ,但没有效果。 This seems to be quite random.这似乎是非常随机的。

I also tried with AsTracking() .我也试过AsTracking()

Before EF Core 3.0, queries that could not be translated into SQL queries were evaluated on the client side.在 EF Core 3.0 之前,无法转换为 SQL 查询的查询在客户端进行评估。 This behaviour was dismissed and an exception is thrown instead of evaluating non-translatable queries on the client side, now.现在,此行为已被取消,并抛出异常,而不是在客户端评估不可翻译的查询。

Also I think the new behaviour should not lead to any big performance issues when you write var result = application.FirstOrDefault(x => x.IsPublished);此外,我认为当您编写var result = application.FirstOrDefault(x => x.IsPublished);时,新行为不应导致任何大的性能问题 separately, because the same thing happened before.分开,因为同样的事情以前发生过。 It was just not visible before.只是以前是看不到的。 (Please correct me if this assumption is wrong!) (如果这个假设是错误的,请纠正我!)

Also you can try following if you want to have one query (did not test this):如果您想进行一个查询(未对此进行测试),您也可以尝试以下操作:

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

You can read about it in detail here: 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您可以在此处详细阅读: https : //docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/break-changes#linq-queries-are-no - 客户评估时间更长

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM