代码之家  ›  专栏  ›  技术社区  ›  Chris

LINQ中的是空功能还是合并功能?

  •  2
  • Chris  · 技术社区  · 14 年前

    我有以下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)
    

    就这样。关于我做错了什么没有更多的线索。帮忙?

    2 回复  |  直到 14 年前
        1
  •  2
  •   Simon    14 年前

    尝试重构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。如果不是,您可以手动预先计算它们,并将两个布尔变量放在它们的位置。

        2
  •  1
  •   code4life    14 年前

    你有没有试过通过调用 Repository.Query().ToList() 在where条款之前?我注意到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();