2011-07-08 25 views
1

我有采取標準對象(具有屬性的列表啞對象)2種類似的方法,調用該標準對象上的「CreateExpression」方法,然後使用返回的表達式來過濾結果。在運行時動態地附加多個LINQ表達式

我的例子之一有一個參數只有一個標準,它沒有問題。我的第二種方法需要List<Criteria>,然後嘗試迭代列表中的每個條件,併爲其生成表達式,然後「和」到前一個表達式。最終的結果應該是我可以在我的linq查詢中使用的一個大表達式。

但是,這第二種方法不起作用。當我使用調試器,我可以看到謂詞與它的內部身體和lambda表達式,但是當它擊中SQL服務器,所有的發送是完全沒有where子句的SELECT語句。

下面是工作(與一個標準對象)的方法:

public static List<Segment> GetByCriteria(Criteria.SegmentCriteria myCriteria) 
     { 
      List<Segment> result = null; 

      List<Segment> qry = db.Segments.AsExpandable<Segment>().Where<Segment>(CreateCriteriaExpression(myCriteria)).ToList<Segment>(); 
      qry = qry.Where<Segment>(CreateCriteriaExpressionForCustomProperties(myCriteria).Compile()).ToList<Segment>(); 


      if (qry != null && qry.Count != 0) 
      { 
       result = qry; 
      } 

      return result; 
     } 

這裏是一個不工作:我使用Predicate Builder生成初始表達

public static List<Segment> GetByCriteria(List<Criteria.SegmentCriteria> myCriteria, Common.MultipleCriteriaMatchMethod myMatchMethod) 
     { 

      List<Segment> result = null; 

      var predicate = PredicateBuilder.True<Segment>(); 
      var customPropertiesPredicate = PredicateBuilder.True<Segment>(); 


      foreach (Criteria.SegmentCriteria x in myCriteria) 
      { 
       if (myMatchMethod == Common.MultipleCriteriaMatchMethod.MatchOnAll) 
       { 
        predicate = predicate.And(CreateCriteriaExpression(x).Expand()); 
        customPropertiesPredicate = customPropertiesPredicate.And(CreateCriteriaExpressionForCustomProperties(x).Expand()); 
       } 
       else if (myMatchMethod == Common.MultipleCriteriaMatchMethod.MatchOnAny) 
       { 
        predicate = predicate.Or(CreateCriteriaExpression(x).Expand()); 
        customPropertiesPredicate = customPropertiesPredicate.Or(CreateCriteriaExpressionForCustomProperties(x).Expand()); 
       } 
      } 


      List<Segment> qry = db.Segments.AsExpandable<Segment>().Where<Segment>(predicate.Expand()).ToList<Segment>(); 
      qry = qry.Where<Segment>(customPropertiesPredicate.Expand().Compile()).ToList<Segment>(); 

      if (qry != null && qry.Count != 0) 
      { 
       result = qry; 
      } 

      return result; 
     } 

。我不相信這些方法存在問題,因爲他們使用第一種(單數)方法。

有人知道這裏發生了什麼嗎?

編輯 我忘了說後端是實體框架。

回答

1

好的,我想通了。

我需要使用「展開()」方法上的所有地方,我在行調用謂詞我在那裏追加謂語。這裏是我的第二種方法的新的固定版本的foreach循環:

foreach (Criteria.SegmentCriteria x in myCriteria) 
      { 
       Criteria.SegmentCriteria item = x; 
       if (myMatchMethod == Common.MultipleCriteriaMatchMethod.MatchOnAll) 
       { 
        predicate = predicate.Expand().And<Segment>(CreateCriteriaExpression(item).Expand()); 
        customPropertiesPredicate = customPropertiesPredicate.Expand().And<Segment>(CreateCriteriaExpressionForCustomProperties(item).Expand()); 
       } 
       else if (myMatchMethod == Common.MultipleCriteriaMatchMethod.MatchOnAny) 
       { 
        predicate = predicate.Expand().Or<Segment>(CreateCriteriaExpression(item).Expand()); 
        customPropertiesPredicate = customPropertiesPredicate.Expand().Or<Segment>(CreateCriteriaExpressionForCustomProperties(item).Expand()); 
       } 
      } 

現在它的工作原理!我在其他question上也找到了有關這方面的細節。

0

裏面的每個循環中,聲明一個局部變量塊內,並將其值設置爲循環變量的值。

 foreach (Criteria.SegmentCriteria x in myCriteria) 
     { 
      Criteria.SegmentCriteria temp = x; 
      if (myMatchMethod == Common.MultipleCriteriaMatchMethod.MatchOnAll) 
      { 
       predicate = predicate.And(CreateCriteriaExpression(temp).Expand()); 
       customPropertiesPredicate = customPropertiesPredicate.And(CreateCriteriaExpressionForCustomProperties(temp).Expand()); 
      } 
      else if (myMatchMethod == Common.MultipleCriteriaMatchMethod.MatchOnAny) 
      { 
       predicate = predicate.Or(CreateCriteriaExpression(temp).Expand()); 
       customPropertiesPredicate = customPropertiesPredicate.Or(CreateCriteriaExpressionForCustomProperties(temp).Expand()); 
      } 
     } 
+0

給了這個鏡頭,但行爲仍然是一樣的。雖然謝謝! –