2010年10月4日

使用Linq進行動態查詢

好吧,我真的不知道該怎麼翻這種查詢,
還記得早期的時候( 其實現在應該也有在大量使用...)
遇到一些複合式的查詢,例如兩個TextBox分別是姓名與電話,
只輸入電話的話,就要列出所有找到的電話,
如果同時輸入姓名與電話的話,就要同時查詢含有電話與姓名的資料。

當時,我們可能會用判斷TextBox是否為空值,來動態加上 Phone = '@Phone' 這種查詢語法,

但是,這在Linq是不適用的= =,
Linq下當然會有一些解決方案,
我這裡提出的是比較簡單的方法,不過缺點是要引入作者寫的dll,
而這位就是鼎鼎大名的C# IN A Nustshel的作者

原文在此如下
http://www.albahari.com/nutshell/predicatebuilder.aspx

以下是我寫得簡單的範例,這部分,可能未來還會再整理。

       //針對CusName欄位進行關鍵字搜索。
public List<Cust> searchKWor(params string[] keywords)
{
  var predicate = PredicateBuilder.False<Cust>();

  foreach (string keyword in keywords)
  {
    string temp = keyword;
    predicate = predicate.Or(cust => cust.CusName.Contains(temp));
  }
  IQueryable<Cust>  searchCustCusName = shDBContext.Cust.AsExpandable().Where(predicate);

  List<Cust> custs = new List<Cust>();

  foreach (var Cust in searchCustCusName)
  {
    custs.Add(Cust);
  }
return custs;
}

//依照欲輸入的CusName欄位進行查詢。
public override List<dynamic> searchKWAll(object o)
{
  Cust cust = o as Cust;
  var predicate = PredicateBuilder.False<Cust>();

  //基本資料查詢
  predicate = predicate.Or(c => c.Sn == cust.Sn );
  predicate = predicate.Or(c => c.CusName.Contains(cust.CusName));
  predicate = predicate.Or(c => c.CusNo.Contains(cust.CusNo));
  predicate = predicate.Or(c => c.Boss.Contains(cust.Boss));
  predicate = predicate.Or(c => c.CusJobName.Contains(cust.CusJobName));
  predicate = predicate.Or(c => c.biten.Contains(cust.biten));
  predicate = predicate.Or(c => c.Reward.Contains(cust.Reward));
  predicate = predicate.Or(c => c.RepName.Contains(cust.RepName));

  //地址
  predicate = predicate.Or(c => c.Addr.Contains(cust.Addr));
  predicate = predicate.Or(c => c.ApplAddr.Contains(cust.Addr));
  //電話
  predicate = predicate.Or(c => c.HPhone.Contains(cust.HPhone));
  predicate = predicate.Or(c => c.OPhone.Contains(cust.HPhone));
  predicate = predicate.Or(c => c.OPhone2.Contains(cust.HPhone));
  predicate = predicate.Or(c => c.MPhone.Contains(cust.HPhone));
  predicate = predicate.Or(c => c.MPhone2.Contains(cust.HPhone));
  predicate = predicate.Or(c => c.FAX.Contains(cust.HPhone));
  predicate = predicate.Or(c => c.FAX2.Contains(cust.HPhone));

  predicate = predicate.Or(c => c.TINo.Contains(cust.TINo));
  predicate = predicate.Or(c => c.IdNo.Contains(cust.IdNo));
  predicate = predicate.Or(c => c.EMP == cust.EMP);

  IQueryable<Cust> searchCustCusName = shDBContext.Cust.AsExpandable().Where(predicate);

  List<dynamic> custs = new List<dynamic>();

  foreach (var Cust in searchCustCusName)
  {
    custs.Add(Cust);
  }
return custs;
}

沒有留言:

張貼留言