我有以下LINQ查询:
return (from r in Repository.Query<Measurement>()
where
r.Postal.ToLowerInvariant() ==
(string.IsNullOrEmpty(postalCode)
? r.Postal : postalCode).ToLowerInvariant()
&&
r.Trait.ToLowerInvariant() ==
(string.IsNullOrEmpty(trait)
? r.Trait : trait).ToLowerInvariant()
select r).ToList();
我的目标是模拟IsNull或Coalesce的功能,但LINQ不喜欢它。我得到以下异常:
The unary operator Not is not defined for the type 'System.String'.
at System.Linq.Expressions.Expression.GetUserDefinedUnaryOperatorOrThrow(ExpressionType unaryType, String name, Expression operand)
at System.Linq.Expressions.Expression.Not(Expression expression, MethodInfo method)
at System.Linq.Expressions.Expression.Not(Expression expression)
at NHibernate.Linq.Visitors.BinaryBooleanReducer.ProcessBinaryExpression(Expression exprToCompare, Expression exprToReturn, ExpressionType nodeType, Expression original)
at NHibernate.Linq.Visitors.BinaryBooleanReducer.VisitBinary(BinaryExpression expr)
at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp)
at NHibernate.Linq.Visitors.ExpressionVisitor.VisitBinary(BinaryExpression b)
at NHibernate.Linq.Visitors.BinaryBooleanReducer.VisitBinary(BinaryExpression expr)
at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp)
at NHibernate.Linq.Visitors.ExpressionVisitor.VisitBinary(BinaryExpression b)
at NHibernate.Linq.Visitors.BinaryBooleanReducer.VisitBinary(BinaryExpression expr)
at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp)
at NHibernate.Linq.Visitors.ExpressionVisitor.VisitLambda(LambdaExpression lambda)
at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp)
at NHibernate.Linq.Visitors.ExpressionVisitor.VisitUnary(UnaryExpression u)
at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp)
at NHibernate.Linq.Visitors.ExpressionVisitor.VisitList(ReadOnlyCollection`1 original)
at NHibernate.Linq.Visitors.ExpressionVisitor.VisitMethodCall(MethodCallExpression m)
at NHibernate.Linq.Visitors.ExpressionVisitor.Visit(Expression exp)
at NHibernate.Linq.NHibernateQueryProvider.TranslateExpression(Expression expression)
at NHibernate.Linq.NHibernateQueryProvider.Execute(Expression expression)
at NHibernate.Linq.Query`1.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at HarvestMap.Website.DataService.GetData(String postalCode, String trait, String measureType, Boolean ffOnly, String apiKey) in D:\Data\Projects\Active\Clients\HarvestMap\src\Website\DataService.svc.cs:line 90
at HarvestMap.Website.DataService.GetDataText3(String postalCode, String trait, String measureType, Boolean ffOnly) in D:\Data\Projects\Active\Clients\HarvestMap\src\Website\DataService.svc.cs:line 162
at SyncInvokeGetDataText3(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
就是这样。没有更多关于我做错的线索。帮助
编辑:当我查询内存中的对象列表时,此查询有效。一旦我转移到NHibernate执行数据库,我就开始获得异常。
答案 0 :(得分:2)
尝试重构IsNullOrEmpty条件,如下所示:
return (from r in Repository.Query<Measurement>()
where
(string.IsNullOrEmpty(postalCode)
|| r.Postal.ToLowerInvariant() == postalCode.ToLowerInvariant()
)
&&
(string.IsNullOrEmpty(trait)
|| r.Trait.ToLowerInvariant() == trait.ToLowerInvariant()
)
select r).ToList();
这可能导致LINQ在发送查询之前评估IsNullOrEmpty。如果没有,你可以手动预先计算它们并在它们的位置放置几个布尔变量。
答案 1 :(得分:1)
您是否尝试过在where子句之前调用Repository.Query().ToList()
来强制执行延迟执行?我注意到它似乎NHibernate试图将string.IsNullOrEmpty()
调用转换为SQL语法(并且失败)。
return (from r in Repository.Query<Measurement>().ToList()
where
r.Postal.ToLowerInvariant() ==
(string.IsNullOrEmpty(postalCode)
? r.Postal : postalCode).ToLowerInvariant()
&&
r.Trait.ToLowerInvariant() ==
(string.IsNullOrEmpty(trait)
? r.Trait : trait).ToLowerInvariant()
select r).ToList();