使用 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)
我在使用带有来自方法参数的参数的 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)