2017-01-13 75 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

希望這個問題很快就會解決。