2017-07-03 138 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代码反编译为可以用另一种语言输出的代码。