使用 linq 包含的方法参数中的参数

use parameter from method argument inside linq contains

我在使用带有来自方法参数的参数的 Contains() 方法时遇到问题。

我正在使用 entity framework 核心 1.1 和 mysql 连接器版本 6.10.0-alpha。

我有这个代码:

public IEnumerable<Message> search(string content) {
    var bla = this.appDbContext.Messages.Where(x => x.Content.Contains("edit")).ToList();
    var bla1 = this.appDbContext.Messages.Where(x => x.Content=="edit").ToList();
    var bla2 = this.appDbContext.Messages.Where(x => x.Content==content).ToList();
    var bla3 = this.appDbContext.Messages.Where(x => x.Content.Contains(content)).ToList();
    ...

前 3 行有效,

然而,第四行(bla3)returns出现如下错误:

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[0] An unhandled exception has occurred while executing the request System.InvalidOperationException: When called from 'VisitChildren', rewriting a node of type 'System.Linq.Expressions.Expression' must return a non-null value of the same type. Alternatively, override 'VisitChildren' and change it to not visit children of this type.

at System.Linq.Expressions.ExpressionVisitor.VisitAndConvert[T](ReadOnlyCollection'1 nodes, String callerName) at Microsoft.EntityFrameworkCore.Query.Expressions.SqlFunctionExpression.VisitChildren(ExpressionVisitor visitor) at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.ExpressionVisitorBase.VisitExtension(Expression node) at Microsoft.EntityFrameworkCore.Query.Expressions.SqlFunctionExpression.Accept(ExpressionVisitor visitor) at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ConditionalRemovingExpressionVisitor.Visit(Expression node) at Microsoft.EntityFrameworkCore.Query.Expressions.LikeExpression.VisitChildren(ExpressionVisitor visitor) at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.ExpressionVisitorBase.VisitExtension(Expression node) at Microsoft.EntityFrameworkCore.Query.Expressions.LikeExpression.Accept(ExpressionVisitor visitor) at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ConditionalRemovingExpressionVisitor.Visit(Expression node) at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitWhereClause(WhereClause whereClause, QueryModel queryModel, Int32 index) at Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection'1 bodyClauses, QueryModel queryModel) at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel) at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitQueryModel(QueryModel queryModel) at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitQueryModel(QueryModel queryModel) at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel) --- End of stack trace from previous location where exception was thrown ---

为什么我不能在 Contains() linq 表达式中使用方法参数中的参数?

我该怎么做才能使用它?

这是我对您的最佳猜测。

当您使用 LINQ to SQL 并将参数化谓词传递给 Where 子句时,编译器将该谓词转换为表达式树。

您的参数化谓词是 x => x.Content.Contains(content)

当运行时使用表达式树时,还有其他约束。您看到 VisitAndConvert 抛出的异常。

在其他三种情况下,我认为编译器要么不需要使用表达式树,要么可以使用不那么复杂的表达式树,在这种情况下您不会看到相同的错误。

如果 MySql 提供程序无法处理复杂的表达式树,那么您可以在内存中而不是在数据库查询中过滤 Messages。但是,如果有很多消息,这可能会填满您的内存,因为您将从数据库中检索所有消息。

this.appDbContext.Messages
    .ToList() // finish the call to the database
    .Where(x => x.Content.Contains(content)) // then filter the data
    .ToList();

显然这是一个真正的错误,而不是我对 entity framework 工作方式的误解。

我们在 entity framework 的 github 问题板上开始讨论它:

在 where 谓词中使用 Contains 时生成错误的查询。 #6687 https://github.com/aspnet/EntityFramework/issues/6687#issuecomment-272543460

然后它被分支到 mysql 错误论坛:

错误 #84505 在带有变量的表达式中使用 Contains 方法会在 EF Core 中抛出异常 http://bugs.mysql.com/bug.php?id=84505

以及 entity framework 的 github 问题板上的一个新的专用问题:

查询:有条件地删除访问者和 sql 函数可能会出错 #7441 https://github.com/aspnet/EntityFramework/issues/7441

希望尽快解决这个问题。

bug在6.10.1版本正式修复: https://www.nuget.org/packages/MySql.Data/6.10.1-beta

https://bugs.mysql.com/bug.php?id=84505

[9 Feb 21:17] Christine Cole

Posted by developer:

Fixed as of the upcoming MySQL Connector/NET 6.10.1 release, and here's the changelog entry:

EF Core: Using the Contains method in an expression with a variable generated an exception.

Thank you for the bug report.

这里是官方发布post:

http://insidemysql.com/mysql-connectornet-6-10-1-beta-has-been-released/

Bugs Fixed

  • EF Core: Using the Contains method in an expression with a variable generated an exception. (Bug #25394204, Bug #84505)