2016-04-28 72 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); 
     } 
    } 
}