2014-10-22 510 views
0

我有一個列表從數據庫中(使用數據集)得到它:C#使用Where(LINQ),以具有四個條件篩選列表

IEnumerable<DataSet.spGetDataRow> MyList = new DataSetTableAdapters.spGetDataTableAdapter().GetData(Date1, Date2, PID, RID).ToList();  

,我有4個複選框

<asp:CheckBox ID="CheckBox1" Text="1" runat="server" /> 
<asp:CheckBox ID="CheckBox2" Text="2" runat="server" /> 
<asp:CheckBox ID="CheckBox3" Text="3" runat="server" /> 
<asp:CheckBox ID="CheckBox4" Text="4" runat="server" /> 

什麼我需要的是過濾 'MYLIST'

我做了以下內容:

if (CheckBox1.Checked && !CheckBox2.Checked && !CheckBox3.Checked && !CheckBox4.Checked) 
{ 
    MyList = MyList.Where(a => a.Avg < 2); 
} 
else if (CheckBox2.Checked && !CheckBox1.Checked && !CheckBox3.Checked && !CheckBox4.Checked) 
{ 
    MyList = MyList.Where(a => a.Avg >= 2 && a.Avg < 3); 
} 
else if (CheckBox3.Checked && !CheckBox2.Checked && !CheckBox1.Checked && !CheckBox4.Checked) 
{ 
    MyList = MyList.Where(a => a.Avg >= 3 && a.Avg < 6); 
} 
else if (CheckBox4.Checked && !CheckBox2.Checked && !CheckBox3.Checked && !CheckBox1.Checked) 
{ 
    MyList = MyList.Where(a => a.Avg >= 6); 
} 

這個工作很好,如果我一次只需要檢查一個複選框,但是如果我想一次檢查2或3,該怎麼辦?

創造這麼多,如果條件不是最好的解決辦法,我需要做的是通過LINQ如果更多鈔票

我在做什麼是創建一個新的MYLIST,和「CONCAT」將過濾進去,但它並沒有結束。

預先感謝您。

+0

能否請您發表你想在你的過濾器放置要求。例如,當「Checkbox1」是唯一選中的複選框,然後是「a.Avg <2」等?謝謝 – Christos 2014-10-22 08:29:14

+2

那麼你會怎麼樣?如果(比如說)複選框2和3被選中,效果會是什麼?如果沒有檢查什麼呢? – 2014-10-22 08:29:31

+0

@JonSkeet:如果沒有任何檢查,顯示所有,如果所有的檢查也顯示所有 – 2014-10-22 08:41:14

回答

2

反之亦然。測試每個複選框。如果它是而不是勾選刪除由此複選框代表的條目。或者更好地採取那些沒有代表的。所以如果CheckBox1是而不是檢查那些條目是而不是 < 2這意味着他們是> = 2。

if (!CheckBox1.Checked) 
    { 
     MyList = MyList.Where(a => a.Avg >= 2); 
    } 
    if (!CheckBox2.Checked) 
    { 
     MyList = MyList.Where(a => a.Avg < 2 || a.Avg >= 3); 
    } 
    if (!CheckBox3.Checked) 
    { 
     MyList = MyList.Where(a => a.Avg < 3 || a.Avg >= 6); 
    } 
    if (!CheckBox4.Checked) 
    { 
     MyList = MyList.Where(a => a.Avg < 6); 
    } 

在接下來的步驟中,你應該預先計算平均值,所以這個函數不會被調用很多次。例如。構建元組(行,平均值),然後過濾平均值,並通過從元組中提取行來取回行。

+0

加'||'修理它。謝謝! – 2014-10-22 08:48:49

0

你的問題使我想用詞典找到解決方案。這將使你的代碼,以一個簡單的兩行像這樣的(當然也需要一個簡單的功能)

int index = CreateIndexFromCheckboxSelected(); 
var result = MyList.Where(x => dict[index].Invoke(x)); 

爲了達到這一解決方案,您需要建立一個辭典數字鍵和FUNC動作值。

的數字鍵,是各個複選框尊重其中checkBox1表示位置1處的比特的布爾邏輯的字節總和,checkbox2位在位置2等....

的函數功能部分是where子句應用於您的sqGetDataRow元素列表所需的lambda表達式

您需要此字典中的16個條目,每個可能的4個複選框的組合中的每一個,每個條目都包含要用於where子句提取所需的spGetDataRow元素。

Dictionary<int, Func<spGetDataRow,bool>> dict = new Dictionary<int, Func<spGetDataRow, bool>>() 
{ 
    {0, (spGetDataRow a) => true},      // No checkboxes checked return all 
    {1, (spGetDataRow a) => a.Avg < 2},     // Only checkbox1 checked 
    {2, (spGetDataRow a) => a.Avg >= 2 && a.Avg < 3}, // Only checkbox2 checked 
    {3, (spGetDataRow a) => a.Avg ????},    // CheckBox1 AND Checkbox2 checked 
    {4, (spGetDataRow a) => a.Avg >= 3 && a.Avg < 6}, // CheckBox3 checked 
    {5, (spGetDataRow a) => a.Avg ????},    // CheckBox3 + ChecBox1 checked 
    {6, (spGetDataRow a) => a.Avg >= 2 && a.Avg < 6}, // CheckBox3 + CheckBox2 checked 
    {7, (spGetDataRow a) => a.Avg ????},    // CheckBox3 + CheckBox2 + CheckBox1 checked  
    {8, (spGetDataRow a) => a.Avg >= 6},    // CheckBox4 checked 
    {9, (spGetDataRow a) => a.Avg ????},    // CheckBox4 + CheckBox1 checked 
    {10, (spGetDataRow a) => a.Avg ????},    // CheckBox4 + CheckBox2 checked 
    {11, (spGetDataRow a) => a.Avg ????},    // CheckBox4 + CheckBox2 + CheckBox1 checked  
    {12, (spGetDataRow a) => a.Avg ????},    // CheckBox4 + CheckBox3 checked 
    {13, (spGetDataRow a) => a.Avg ????},    // CheckBox4 + CheckBox3 + CheckBox1 checked 
    {14, (spGetDataRow a) => a.Avg ????},    // CheckBox4 + CheckBox3 + CheckBox2 checked 
    {15, (spGetDataRow a) => true}      // All checkboxes selected return all 
}; 

上面的例子包含了正確的λ只爲信息,我可以從你的問題中提取,但你可以看到它是早晚的事情,以取代您所需要的各種正確的佔位符拉姆達複選框的組合。

要完成的示例中,只有一件遺失了,但是這是相當瑣碎

public int CreateIndexFromCheckboxSelected() 
{ 
    int chk1 = (CheckBox1.Checked ? 1 : 0); 
    int chk2 = (CheckBox2.Checked ? 2 : 0); 
    int chk3 = (CheckBox3.Checked ? 4 : 0); 
    int chk4 = (CheckBox4.Checked ? 8 : 0); 
    return (chk1 + chk2 + chk3 + chk4); 
}