2012年7月9日 星期一

如何在 Linq 裡面使用類似 SQL 的 IN 的語法?

需求是這樣的,使用者會輸入一個日期區間、並挑選業務員,
我在查詢的畫面會【列出所有的主檔資料】讓使用者勾選要列印哪一個主檔的資料,
但是當使用者按下一個【filter】的按鈕之後,
我會過濾出那個業務員有業績的資料,
然後取代剛剛那個【列出所有的主檔資料】的畫面讓使用者勾選。
以前的作法會大概會是過濾的時候順便 JOIN 主檔的資料,
然後列在主檔的畫面讓使用者勾選。

不過我在作的時候突然想到,我前端都已經有全部的主檔資料了,
為什麼還要再 JOIN 一次呢?
為什麼還要再增加那台五年前很強的主機的負擔呢?

所以我就想說有沒有辦法可以在前端作 JOIN 或是用 IN 的方式呢?
摸索了一下, Linq 沒有 IN 可以用,不過找到了另一個方式可以代替,
在我還沒有找到其他方式之前就先這麼辦吧!

測試的畫面大概長這樣!最左邊列出所有的產品,中間列出指定業務員有交易過的產品。


當業務員選擇 Frankie 的時候,則只列出 Frankie 有交易過的產品資料。
所以就不是全部的產品了!


選擇 Mork 的時候,顯示出有交易過的產品又更少了!


程式碼如下:
  1. string sales = leSales.EditValue.ToString();
  2.  
  3. DataTable filterList = DBUtility.GetDataFromDB("deal",
  4.     string.Format("SELECT DISTINCT product FROM deal WHERE sales = '{0}'", sales));
  5.  
  6. var q = filterList.AsEnumerable()
  7.     .Select(f => f.FieldByName("product").AsString);
  8. var filterResult = allProducts.AsEnumerable()
  9.     .Where(r => q.Contains(r.FieldByName("code").AsString));
  10.  
  11. DataTable filterProducts = null;
  12. if (filterResult.Count() > 0) filterProducts = filterResult.CopyToDataTable();
  13. grdFilter.DataSource = filterProducts;

這邊有用 DevExpress 的元件,所以有些物件的屬性不懂就跳過吧!

1.先取得業務員代號。

3.取得業務員曾交易過的產品代號。

6.將交易過的產品存到 q 裡面。

8.這個時候就可以用 q.Contains 當 SQL IN 來用了!

13.最後將過濾過的資料集塞回去 Grid 就可以了!


沒有留言:

張貼留言