2016-04-28 42 views
1

我一直在使用LINQ查询,但我碰到了一个动态where子句的障碍。我想检查一个条件,如果是的话,然后添加到我的查询。问题是,哪里在使用我的一个连接的范围变量之一。我的工作查询如下:如何写联接范围变量的动态where子句

var query = from project in db.ProjMasters 
      join pd in db.ProjDetails on project.ProjMasterID equals pd.ProjMasterID 
      join dc in db.DivCodes on project.DivisionCode equals dc.DivCode1 
      join ec in db.EmpCodes on project.ProjManager equals ec.UserNm 
      join ptc in db.ProjTypeCodes on pd.ProjTypeCode equals ptc.ProjTypeCode1 
      join psc in db.ProjStatusCodes on pd.ProjStatusCode equals psc.ProjStatusCode1 
      where pd.ProjDeleteDate == null 
      orderby project.Title 
      select new 
      { 
        project.ProjMasterID, 
        project.Title, 
        pd.ProjDesc, 
        pd.ContractNum, 
        pd.ProjDetailID, 
        dc.DivNm, 
      } 
      if (sTitle != null) 
      { 
       query = query.Where(x => x.Title.Contains(sTitle)); 
      } 

TYPEDESC是db.ProjTypeCodes一个类型,所以我想说

if (sProjType != null) 
{ 
    query = query.Where(x => x.TypeDesc==sProjType); 
} 

但我只能用其中在项目类型; “AnonymousType#1不包含'TypeDesc'的定义...”我如何在ptc.TypeDesc中使用动态的地方?

+1

那么,错误是明确的,你没有选择ptc.TypeDesc,只需将其添加到您的选择... – Gusman

+0

谢谢古斯曼!如果你有任何想法,我已经用这个圈子走了多久。 – KFP

回答

0

问题在于您的订单,如果您选择丢弃不在select语句中的所有数据,如果您使用Inline if语句,那么您可以轻松地在第一个where子句中执行此操作,或者您可以在虽然你可以从一个LINQ查询LINQ statments有convery

var query = from project in db.ProjMasters 
      join pd in db.ProjDetails on project.ProjMasterID equals pd.ProjMasterID 
      join dc in db.DivCodes on project.DivisionCode equals dc.DivCode1 
      join ec in db.EmpCodes on project.ProjManager equals ec.UserNm 
      join ptc in db.ProjTypeCodes on pd.ProjTypeCode equals ptc.ProjTypeCode1 
      join psc in db.ProjStatusCodes on pd.ProjStatusCode equals psc.ProjStatusCode1 
      where pd.ProjDeleteDate == null 
       && sProjType!= null ? ptc.TypeDesc==sProjType): true 
      orderby project.Title 
      select new 
      { 
        project.ProjMasterID, 
        project.Title, 
        pd.ProjDesc, 
        pd.ContractNum, 
        pd.ProjDetailID, 
        dc.DivNm, 
      } 
      if (sTitle != null) 
      { 
       query = query.Where(x => x.Title.Contains(sTitle)); 
      } 
+0

出于某种原因,这种方式比Gusman的方式返回更多的记录,这是返回正确的数字(比较原始的SQL查询)。 – KFP

0

使用的IQueryable这里更多信息为什么link

IQueryable<{CreateNewSelectObjects}> query = ... ; 
if (sProjType != null) 
{ 
    query = query.Where(x => x.TypeDesc==sProjType); 
} 
+0

不会帮助,因为该字段不在数据集中 – MikeT

0

您所查询的是很好的候选人想我最近的自定义扩展方法发布到"Nullable object must have a value" exception after checking for null on a non-primitive/non-struct object

这个想法很简单。您可以直接建立自己的动态标准查询内部,方法如果使用if SIN转换它:

var query = (from project in db.ProjMasters 
      join pd in db.ProjDetails on project.ProjMasterID equals pd.ProjMasterID 
      join dc in db.DivCodes on project.DivisionCode equals dc.DivCode1 
      join ec in db.EmpCodes on project.ProjManager equals ec.UserNm 
      join ptc in db.ProjTypeCodes on pd.ProjTypeCode equals ptc.ProjTypeCode1 
      join psc in db.ProjStatusCodes on pd.ProjStatusCode equals psc.ProjStatusCode1 
      where pd.ProjDeleteDate == null 
       && (sProjType == null || ptc.TypeDesc == sProjType) 
       && (sTitle == null || project.Title.Contains(sTitle)) 
      orderby project.Title 
      select new 
      { 
        project.ProjMasterID, 
        project.Title, 
        pd.ProjDesc, 
        pd.ContractNum, 
        pd.ProjDetailID, 
        dc.DivNm, 
      }).ReduceConstPredicates(); 

附:下面是使用的方法的情况下,一些源代码恰好与链接:

public static class QueryableExtensions 
{ 
    public static IQueryable<T> ReduceConstPredicates<T>(this IQueryable<T> source) 
    { 
     var reducer = new ConstPredicateReducer(); 
     var expression = reducer.Visit(source.Expression); 
     if (expression == source.Expression) return source; 
     return source.Provider.CreateQuery<T>(expression); 
    } 

    class ConstPredicateReducer : ExpressionVisitor 
    { 
     private int evaluateConst; 
     private bool EvaluateConst { get { return evaluateConst > 0; } } 
     private ConstantExpression TryEvaluateConst(Expression node) 
     { 
      evaluateConst++; 
      try { return Visit(node) as ConstantExpression; } 
      catch { return null; } 
      finally { evaluateConst--; } 
     } 
     protected override Expression VisitUnary(UnaryExpression node) 
     { 
      if (EvaluateConst || node.Type == typeof(bool)) 
      { 
       var operandConst = TryEvaluateConst(node.Operand); 
       if (operandConst != null) 
       { 
        var result = Expression.Lambda(node.Update(operandConst)).Compile().DynamicInvoke(); 
        return Expression.Constant(result, node.Type); 
       } 
      } 
      return EvaluateConst ? node : base.VisitUnary(node); 
     } 
     protected override Expression VisitBinary(BinaryExpression node) 
     { 
      if (EvaluateConst || node.Type == typeof(bool)) 
      { 
       var leftConst = TryEvaluateConst(node.Left); 
       if (leftConst != null) 
       { 
        if (node.NodeType == ExpressionType.AndAlso) 
         return (bool)leftConst.Value ? Visit(node.Right) : Expression.Constant(false); 
        if (node.NodeType == ExpressionType.OrElse) 
         return !(bool)leftConst.Value ? Visit(node.Right) : Expression.Constant(true); 
        var rightConst = TryEvaluateConst(node.Right); 
        if (rightConst != null) 
        { 
         var result = Expression.Lambda(node.Update(leftConst, node.Conversion, rightConst)).Compile().DynamicInvoke(); 
         return Expression.Constant(result, node.Type); 
        } 
       } 
      } 
      return EvaluateConst ? node : base.VisitBinary(node); 
     } 
     protected override Expression VisitConditional(ConditionalExpression node) 
     { 
      if (EvaluateConst || node.Type == typeof(bool)) 
      { 
       var testConst = TryEvaluateConst(node.Test); 
       if (testConst != null) 
        return Visit((bool)testConst.Value ? node.IfTrue : node.IfFalse); 
      } 
      return EvaluateConst ? node : base.VisitConditional(node); 
     } 
     protected override Expression VisitMember(MemberExpression node) 
     { 
      if (EvaluateConst || node.Type == typeof(bool)) 
      { 
       var expressionConst = node.Expression != null ? TryEvaluateConst(node.Expression) : null; 
       if (expressionConst != null || node.Expression == null) 
       { 
        var result = Expression.Lambda(node.Update(expressionConst)).Compile().DynamicInvoke(); 
        return Expression.Constant(result, node.Type); 
       } 
      } 
      return EvaluateConst ? node : base.VisitMember(node); 
     } 
     protected override Expression VisitMethodCall(MethodCallExpression node) 
     { 
      if (EvaluateConst || node.Type == typeof(bool)) 
      { 
       var objectConst = node.Object != null ? TryEvaluateConst(node.Object) : null; 
       if (objectConst != null || node.Object == null) 
       { 
        var argumentsConst = new ConstantExpression[node.Arguments.Count]; 
        int count = 0; 
        while (count < argumentsConst.Length && (argumentsConst[count] = TryEvaluateConst(node.Arguments[count])) != null) 
         count++; 
        if (count == argumentsConst.Length) 
        { 
         var result = Expression.Lambda(node.Update(objectConst, argumentsConst)).Compile().DynamicInvoke(); 
         return Expression.Constant(result, node.Type); 
        } 
       } 
      } 
      return EvaluateConst ? node : base.VisitMethodCall(node); 
     } 
    } 
}