2017-07-03 113 views
1

我試圖通過一般一個輔助類來過濾實體框架中的核心了一定的成果,但我發現這個錯誤,我不知道爲什麼:通用Linq查詢NotSupportedException異常:無法解析表達式

NotSupportedException: Could not parse expression 'value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable'1[eVendCustomerDAL.DomainModels.Bin]).Any(__funcTest_0)': The given arguments did not match the expected arguments: Object of type 'System.Linq.Expressions.TypedParameterExpression' cannot be converted to type 'System.Linq.Expressions.LambdaExpression'.

而這正是錯誤發生的事情:

public virtual Revision<DTO> GetStateAsRevision(
     Expression<Func<Domain, bool>> query) { 
     //get all the stateful data from the database 
     DbSet<Domain> oriSet = db.Set<Domain>(); 
     //query all the data 
     List<Domain> oriList = oriSet.Where(query).ToList(); 

的錯誤似乎是因爲query參數我通過推的發生,它只會發生的運行時間。我不確定它的通用性是否應該歸咎於它。泛型是類而不是接口。

where DTO : BaseRevisionDTO 
where Domain : BaseTrackedObject 
where DomainRevision : BaseRevision 

我然後使用以下片段構建表達:

private Expression<Func<Domain, bool>> GetDomainSearchExpression(Func<Domain, bool> shortFunction) { 
     DbSet<Domain> modelTable = CustomerContext.Set<Domain>(); 

     Expression<Func<Domain, bool>> expr = 
     d => 
     modelTable.Any(shortFunction); 

     return expr; 
    } 

    protected override Func<DomainModels.Bin, bool> GetDomainSearchFunction() { 
     return x => x.Station.Machine.UniqueId == MachineID; 
    } 

編輯1:

所以,如果我調用上述代碼如下所示:

 GetStateAsRevision(GetDomainSearchExpression(GetDomainSearchFunction())); 

它會在以下錯誤:

 List<Domain> oriList = oriSet.Where(query).ToList(); 

這是整個堆棧跟蹤:

NotSupportedException: Could not parse expression 'value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[eVendCustomerDAL.DomainModels.Bin]).Any(__shortFunction_0)': The given arguments did not match the expected arguments: Object of type 'System.Linq.Expressions.TypedParameterExpression' cannot be converted to type 'System.Linq.Expressions.LambdaExpression'. 
Remotion.Linq.Parsing.Structure.MethodCallExpressionParser.CreateExpressionNode(Type nodeType, MethodCallExpressionParseInfo parseInfo, Object[] additionalConstructorParameters) 
Remotion.Linq.Parsing.Structure.MethodCallExpressionParser.Parse(string associatedIdentifier, IExpressionNode source, IEnumerable<Expression> arguments, MethodCallExpression expressionToParse) 
Remotion.Linq.Parsing.Structure.ExpressionTreeParser.ParseMethodCallExpression(MethodCallExpression methodCallExpression, string associatedIdentifier) 
Remotion.Linq.Parsing.Structure.ExpressionTreeParser.ParseTree(Expression expressionTree) 
Remotion.Linq.Parsing.Structure.QueryParser.GetParsedQuery(Expression expressionTreeRoot) 
Remotion.Linq.Parsing.ExpressionVisitors.SubQueryFindingExpressionVisitor.Visit(Expression expression) 
System.Linq.Expressions.ExpressionVisitor.VisitLambda<T>(Expression<T> node) 
System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor) 
Remotion.Linq.Parsing.ExpressionVisitors.SubQueryFindingExpressionVisitor.Visit(Expression expression) 
System.Linq.Enumerable+SelectListPartitionIterator.ToArray() 
System.Linq.Enumerable.ToArray<TSource>(IEnumerable<TSource> source) 
Remotion.Linq.Parsing.Structure.MethodCallExpressionParser.Parse(string associatedIdentifier, IExpressionNode source, IEnumerable<Expression> arguments, MethodCallExpression expressionToParse) 
Remotion.Linq.Parsing.Structure.ExpressionTreeParser.ParseMethodCallExpression(MethodCallExpression methodCallExpression, string associatedIdentifier) 
Remotion.Linq.Parsing.Structure.ExpressionTreeParser.ParseTree(Expression expressionTree) 
Remotion.Linq.Parsing.Structure.QueryParser.GetParsedQuery(Expression expressionTreeRoot) 
Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore<TResult>(Expression query, INodeTypeProvider nodeTypeProvider, IDatabase database, ILogger logger, Type contextType) 
Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler+<>c__DisplayClass19_0.<CompileQuery>b__0() 
Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore<TFunc>(object cacheKey, Func<Func<QueryContext, TFunc>> compiler) 
Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute<TResult>(Expression query) 
Remotion.Linq.QueryableBase.GetEnumerator() 
System.Collections.Generic.List..ctor(IEnumerable<T> collection) 
System.Linq.Enumerable.ToList<TSource>(IEnumerable<TSource> source) 
eVendWebAPI.Helpers.DALHelpers.GetRevisionHelper.GetStateAsRevision(Expression<Func<DomainModel, bool>> query) in GetRevisionHelper.cs 
+ 
      List<DomainModel> oriList = oriSet.Where(query).ToList(); 
eVendWebAPI.Helpers.DALHelpers.GetRevisionHelper.GetRevision(Expression<Func<DomainModel, bool>> query) in GetRevisionHelper.cs 
+ 
      return GetStateAsRevision(query); 
eVendWebAPI.Areas.Customer.Controllers.Base.BaseAPIRevisionController.Get() in BaseAPIRevisionController.cs 
+ 
      return Ok(helper.GetRevision(searchExpr)); 
lambda_method(Closure , object , Object[]) 
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeActionMethodAsync>d__27.MoveNext() 
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeNextActionFilterAsync>d__25.MoveNext() 
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context) 
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) 
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeNextResourceFilter>d__22.MoveNext() 
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context) 
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) 
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker+<InvokeAsync>d__20.MoveNext() 
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
Microsoft.AspNetCore.Builder.RouterMiddleware+<Invoke>d__4.MoveNext() 
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
Microsoft.AspNetCore.Builder.RouterMiddleware+<Invoke>d__4.MoveNext() 
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+<Invoke>d__18.MoveNext() 
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware+<Invoke>d__18.MoveNext() 
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
Microsoft.VisualStudio.Web.BrowserLink.BrowserLinkMiddleware+<ExecuteWithFilter>d__7.MoveNext() 
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__7.MoveNext() 
+1

你的'shortFunction'是'Func <>'而不是'Expression',所以它不能轉換爲SQL。嘗試使其爲'Expression >'來代替。 – NetMage

+0

嘿謝謝你!那是什麼呢? – Smithy

回答

1

shortFunctionFunc<>,而不是一個Expression所以不能轉換爲SQL。嘗試改爲使用Expression<Func<>>

C#編譯器具有特殊的邏輯來拉姆達轉換成兩種類型 - 如果所期望的結果類型爲Func<>然後將其轉換爲已編譯的代碼,如果如果Expression它其轉換爲Expression樹代表該代碼的結果類型(爲LINQ添加了一個作弊)。數據提供者可以讀取表達式樹併發出有問題的數據庫的代碼(例如SQL),但不能將編譯後的IL代碼反編譯爲可以用另一種語言輸出的代碼。