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

时间:2017-01-13 15:12:27

标签: .net-core entity-framework-core mysql-connector

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

我正在使用实体框架核心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();
    ...

前三行有效,

但是,第四行(bla3)返回以下错误:

  

失败:   Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware [0]         执行请求时出现未处理的异常System.InvalidOperationException:从'VisitChildren'调用时,   重写“System.Linq.Expressions.Expression”类型的节点必须   返回相同类型的非null值。或者,覆盖   'VisitChildren'并将其更改为不访问此类儿童。

     

在   System.Linq.Expressions.ExpressionVisitor.VisitAndConvert [T](ReadOnlyCollection'1   nodes,String callerName)at   Microsoft.EntityFrameworkCore.Query.Expressions.SqlFunctionExpression.VisitChildren(ExpressionVisitor   访客)   Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.ExpressionVisitorBase.VisitExtension(表达式   节点)   Microsoft.EntityFrameworkCore.Query.Expressions.SqlFunctionExpression.Accept(ExpressionVisitor   访客)   Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ConditionalRemovingExpressionVisitor.Visit(表达式   节点)   Microsoft.EntityFrameworkCore.Query.Expressions.LikeExpression.VisitChildren(ExpressionVisitor   访客)   Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.ExpressionVisitorBase.VisitExtension(表达式   节点)   Microsoft.EntityFrameworkCore.Query.Expressions.LikeExpression.Accept(ExpressionVisitor   访客)   Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ConditionalRemovingExpressionVisitor.Visit(表达式   节点)   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)   ---从抛出异常的先前位置开始的堆栈跟踪结束---

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

我该怎么做才能使用它?

3 个答案:

答案 0 :(得分:1)

显然这是一个真正的错误,而不是我在实体框架的工作方式中理解的东西。

我们在实体框架的github问题板上开始讨论它:

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

然后它分支到mysql bug论坛:

错误#84505在表达式中使用包含方法的变量在EF Core中引发异常 http://bugs.mysql.com/bug.php?id=84505

以及实体框架的github问题板中的新专用问题:

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

希望很快就能解决这个问题。

答案 1 :(得分:0)

这是我对你的最佳猜测。

当您使用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();

答案 2 :(得分:0)

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

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

  

[2月9日21:17] Christine Cole

     

发布者发布:

     

修正了即将发布的MySQL Connector / NET 6.10.1版本,以及更改日志条目:

     

EF Core:在带有变量的表达式中使用Contains方法   产生了一个例外。

     

感谢您提供错误报告。

这是官方发布的帖子:

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

  

错误修复

     
      
  • EF Core:在带有变量的表达式中使用Contains方法生成异常。 (Bug#25394204,Bug#84505)
  •