2017-01-13 117 views
2

我有一个使用Contains()方法的问题,方法参数来自方法参数。linq中使用方法参数的参数包含

我使用实体框架核心1.1和MySQL连接器版本6.10.0-α。

我有这样的代码:

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)返回以下错误:

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表达式中的方法参数的参数?

我能做些什么来使用它?

回答

0

错误正式固定在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.

,这里是官方发布的帖子:

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)
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(); 
+0

这是一个很好的解决方法,然而,正如你写的 - 在大数据的情况下,这将填满内存,并不会很好。 我刚刚写了一个正式答案,指出这是一个真正的bug,并且实体框架的团队和mysql连接器团队都知道它。 – shahaf

+0

很高兴知道。感谢您的评论。我应该删除我的答案吗? –

+0

我找不到删除它的原因,这可能会帮助没有大量数据的人,因此不会有内存问题。谢谢。 – shahaf

1

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

我们开始在实体框架的GitHub的问题董事会这里说起吧:

使用时

错误查询生成内部包含其中谓语。#6687 https://github.com/aspnet/EntityFramework/issues/6687#issuecomment-272543460

,然后将其支到mysql的错误论坛:

错误#84505使用包含在表达方法与变量EF核心抛出异常 http://bugs.mysql.com/bug.php?id=84505

,并在实体框架的github问题主板中的一个新的专用问题:

查询:可能的错误条件删除访客和SQL功能#7441 https://github.com/aspnet/EntityFramework/issues/7441

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