2013-02-20 20 views
1

我想用LinqPad建立一個基本的動態Linq查詢。我的方法要求用戶選擇1 - 3選項,然後根據其輸入動態構建查詢。動態Linq查詢不按預期工作 - 我做錯了什麼?

public void FilteredPropertySearch() 
{ 
    bool addAnotherOption = true; 
    int option; 
    Dictionary<int, bool> parameters = new Dictionary<int, bool>(); 
    var predicate = PredicateBuilder.False<ResidentialProperty>(); 

    Console.WriteLine("Follow instructions to filter property search results"); 

do 
{ 
    // get user input 

    option = int.Parse(Console.ReadLine()); 

    switch(option) 
    { 
     case 1: 
      parameters.Add(1, true); 
      break; 

    // more cases - when case 0 addAnotherOption = false, loop ends 

     default: 
      Console.WriteLine("That was not a valid option"); 
      break; 
    } 

}while(addAnotherOption == true); 

    foreach(KeyValuePair<int, bool> p in parameters) 
{ 
    if(p.Key == 1 && p.Value == true) 
     predicate = predicate.Or (c => c.HasBackGarden); 
    if(p.Key == 2 && p.Value == true) 
     predicate = predicate.Or (c => c.HasFrontGarden); 
    if(p.Key == 3 && p.Value == true) 
     predicate = predicate.Or (c => c.HasSecureParking); 
} 

ResidentialProperties.Where (predicate).Dump(); 

} 

foreach循環應建立基於用戶的輸入查詢,但是當,例如,我做在字典真正的第一個值,並選擇沒有別人,它不返回任何結果。它肯定應該,因爲我知道我的數據庫表中有一些值滿足Key(1)爲真。

我應該在query之後做些別的什麼嗎?ifforeach

編輯

我用過的謂詞建設者,而不是和它似乎是(種)當我使用predicate.Or(按照編輯的代碼)工作,但它只返回我選擇第一個選項,它不是構建表達式樹。我認爲將predicate.Or更改爲predicate.And會將每個選定的用戶輸入添加到過濾器表達式中。

如果所有三個選項都是由用戶選擇的,我只希望返回HasBackGarden,HasFrontGarden和HasSecureParking列都爲true的行。我該如何做到這一點?

+1

我只能在這裏看到'query'被指定爲'Enumerable.Empty <>'(即您的類型的空列表)。你如何將它與你要過濾的數據關聯起來? – 2013-02-20 16:49:25

+0

我這樣做是因爲我無法去'var query;'。在Linqpad中,我正在查詢名爲ResidentialProperties的表,該表映射到名爲ResidentialProperty的模型。我需要像select一樣用'query'做些什麼嗎? – MattSull 2013-02-20 16:55:17

回答

3

如果你想限制你的結果設定爲那些滿足所有的條件記錄,那麼你是正確的,你應該使用.And,而不是.Or,但爲了做到這一點,你需要開始與PredicateBuilder.True<ResidentialProperty>()而不是False

這是因爲在添加任何過濾器之前,正確的結果集包含所有記錄,並且每個後續過濾器都會限制結果集。如果你從False開始,那麼這些記錄都不可能滿足謂詞。

+0

輝煌,那有效。非常感謝。 – MattSull 2013-02-20 17:49:09

1

從你的代碼看起來你正在操作var「查詢」這是一個空的枚舉。請記住,您所稱的查詢是數據集,Where語句是對該數據集的查詢。所以第一個查詢是在一個空的數據集上,它看起來像來自foreach的額外查詢將只改進這個空集。

此外,你可以做.Where(q => q.HasWhatever),因爲這些都是bools。

+0

那麼我應該先填充所有可能的行的查詢?這對性能不會有壞處嗎? – MattSull 2013-02-20 17:03:36

+0

該變量通常是DbSet或某個不是「已填充」數據集的枚舉,而是指向您的數據源。使用實體框架或其他東西你的集合將是一個數據庫支持的集合,直到查詢實際發生時纔會被填充。 – Thabo 2013-02-20 17:07:17

+0

假設您使用的是EF,那麼在您的DBContext中,映射到包含數據庫的數據庫應該有一個DbSet ,您可以按照您在此處查詢的方式進行查詢。 – Thabo 2013-02-20 17:17:19