2016-03-08 27 views
1

(如果標題是不是代表這個問題,請告訴我,我不能拿出一個很好的簡短描述)在asp.NET動態查詢與SQL服務器

我試圖實施高級搜索功能爲我的Web應用程序。該搜索必須能夠搜索很多可能的組合。 enter image description here

如圖所示,每個組(AND或OR)可以有另一組可以相等或不相等的組。圖片應該導致看起來像這樣在where子句中:

WHERE (Application like '%User%' AND Host not like '%fjzhykjety%') OR (REMOTE_HOST like '%uykirlyy%' AND REMOTE_PORT not like '%55555%') 

應用,主機和REMOTE_HOST是字符串,REMOTE_PORT是一個可空int類型。我也有一個必須可搜索的GUID。

在這個前端搜索是寫在角的時刻,給了我下面的JSON(JSON的依賴於嵌套組和條件)的例子:

{ 
    "group": { 
     "operator": "OR", 
     "rules": [ 
      { 
       "group": { 
        "operator": "AND", 
        "rules": [ 
         { 
          "condition": "=", 
          "field": { 
           "name": "Application", 
           "type": "select" 
          }, 
          "data": "User" 
         }, 
         { 
          "condition": "<>", 
          "field": { 
           "name": "Host", 
           "type": "text" 
          }, 
          "data": "fjzhykjety" 
         } 
        ] 
       } 
      }, 
      { 
       "group": { 
        "operator": "AND", 
        "rules": [ 
         { 
          "condition": "=", 
          "field": { 
           "name": "REMOTE_HOST", 
           "type": "text" 
          }, 
          "data": "uykirlyy" 
         }, 
         { 
          "condition": "<>", 
          "field": { 
           "name": "REMOTE_PORT", 
           "type": "number" 
          }, 
          "data": 55555 
         } 
        ] 
       } 
      } 
     ] 
    } 
} 

我需要一種方法來這個數據發送到我的.NET應用程序(使用REST API)並在數據庫中查詢它。我查看了動態linq進行查詢,但由於json文件的格式並不總是相同,因此很難在C#中爲它創建類,併爲此搜索構建動態linq查詢。

實現此高級搜索的最佳方式是什麼?

回答

1

以下是動態查詢的示例。你也可以結合你的查詢linqkit是很好的謂詞構建器。

http://www.albahari.com/nutshell/linqkit.aspx這裏

IQueryable<Product> SearchProducts (params string[] keywords) 
{ 
    var predicate = PredicateBuilder.False<Product>(); 

    foreach (string keyword in keywords) 
    { 
    string temp = keyword; 
    predicate = predicate.Or (p => p.Description.Contains (temp)); 
    } 

    return dataContext.Products.Where (predicate); 
} 

編輯

你需要表達 https://github.com/scottksmith95/LINQKit

public List<CustomerPointsDetail> GetCustomerPointsDetails(
      int customerId, 
      int? catalogRewardId = null, 
      long? couponId = null, 
      long? transactionId = null, 
      CustomerPointsDetailStatus? inStatus = null, 
      CustomerPointsDetailStatus? notInStatus = null, 
      bool? isPointsGreaterThanZero = null, 
      bool? isRemainingPointsGreaterThanZero = null, 
      CustomerPointsDetailOperationType? operationType = null, 
      DateTime? startDate = null, 
      DateTime? endDate = null, 
      bool isExpiredRecordsIncluded = false) 
     { 
      var query = this.customerPointsDetailRepository.Table.Where(cpd => cpd.CustomerId == customerId); 

      if (catalogRewardId.HasValue) 
      { 
       query = query.Where(cpd => cpd.CatalogRewardId == catalogRewardId); 
      } 

      if (couponId.HasValue) 
      { 
       query = query.Where(cpd => cpd.CouponId == couponId); 
      } 

      if (transactionId.HasValue) 
      { 
       query = query.Where(cpd => cpd.TransactionId == transactionId); 
      } 

      if (inStatus.HasValue) 
      { 
       query = query.Where(cpd => cpd.Status == inStatus); 
      } 

      if (notInStatus.HasValue) 
      { 
       query = query.Where(cpd => cpd.Status != notInStatus); 
      } 

      if (isRemainingPointsGreaterThanZero.HasValue) 
      { 
       if (isRemainingPointsGreaterThanZero.GetValueOrDefault()) 
       { 
        query = query.Where(cpd => cpd.RemainingPoints.HasValue && cpd.RemainingPoints > 0); 
       } 
       else 
       { 
        query = query.Where(cpd => cpd.RemainingPoints.HasValue && cpd.RemainingPoints < 0); 
       } 
      } 

      if (isPointsGreaterThanZero.HasValue) 
      { 
       if (isPointsGreaterThanZero.GetValueOrDefault()) 
       { 
        query = query.Where(cpd => cpd.Points > 0); 
       } 
       else 
       { 
        query = query.Where(cpd => cpd.Points < 0); 
       } 
      } 

      if (operationType.HasValue) 
      { 
       query = query.Where(cpd => cpd.OperationType == operationType); 
      } 

      if (!isExpiredRecordsIncluded) 
      { 
       query = query.Where(cpd => !cpd.PointsExpireDate.HasValue 
              || (cpd.PointsExpireDate.HasValue && cpd.PointsExpireDate > DateTime.Now)); 
      } 

      if (startDate.HasValue) 
      { 
       query = query.Where(cpd => cpd.CreateDate >= startDate); 
      } 

      if (endDate.HasValue) 
      { 
       query = query.Where(cpd => cpd.CreateDate <= endDate); 
      } 

      query = query.OrderBy(cpd => cpd.PointsExpireDate); 

      return query.ToList(); 
     } 

Linqkit樣品給你的方法。您可以與Linqkit結合使用。

Expression<Func<Product, bool>> e1 = DynamicExpression.ParseLambda<Product, bool>("Type= \"Type_A\"");  

    OR 

Expression<Func<Product, bool>> e1 = p => p.Type="Type_A"; 

電話之前,你在計劃SearchProduct

var expressions = new Dictionary<Expression<Func<Product, bool>>, bool>(); 

Expression<Func<Product, bool>> e1 = p => p.Type="Type_A"; 
Expression<Func<Product, bool>> e2 = p => p.Type="Type_B"; 

expressions.Add(e1,true); 
expressions.Add(e2,true); 

SearchProducts(expressions); //send expression list for evoluate 

    IQueryable<Product> SearchProducts (Dictionary<Expression<Func<Product, bool>>, bool> expressionList) 
    { 
     var predicate = PredicateBuilder.False<Product>(); 

     foreach(expression in expressionList) 
     { 

      if(expression.Value) // AND 
      { 
       predicate = predicate.And(expression.Key); 
      }else // OR 
      { 
       predicate = predicate.Or(expression.Key); 
      } 

     } 
     . 
     . 
    } 
+0

感謝您的回答,linqkit看起來很有希望爲AND和OR子句。但是,動態查詢必須能夠多次檢查相同的屬性。如下例所示: ![相同的屬性](http://i.imgur.com/eEbjIL8.png) –

+0

有多個條件查詢,使用AND或OR子句構建。 Linqkit爲你提供了簡單的方法。你可以用最後一個方法給N次相同的屬性 –