2016-03-08 90 views
4

我是LINQ查詢的'新手'有另一個這樣的問題,我有事情要做,但不知道這是否是最有效的方法。在我的項目,我在一個真正的DB工作,但是爲了簡單的緣故,在這裏我會凝結下來給員工的一個簡單的列表:篩選條件搜索使用LINQ

var employees = new List<Employee> 
     { 
      new Employee { Id = 0, firstName = "James", LastName = "Bond", Manager = "M", StartDate = DateTime.Now }, 
      new Employee { Id = 1, firstName = "Eric", LastName = "Bond", Manager = "M", StartDate = DateTime.Now }, 
      new Employee { Id = 2, firstName = "Sue", LastName = "Milton", Manager = "Q", StartDate = DateTime.Now }, 
      new Employee { Id = 3, firstName = "Olivia", LastName = "Milton", Manager = "M", StartDate = DateTime.Now }, 
      new Employee { Id = 4, firstName = "Alice", LastName = "Raymond", Manager = "M", StartDate = DateTime.Now }, 
      new Employee { Id = 5, firstName = "James", LastName = "Skywalker", Manager = "M", StartDate = DateTime.Now }, 
      new Employee { Id = 6, firstName = "Luke", LastName = "Skywalker", Manager = "M", StartDate = DateTime.Now }, 

     }; 

我有一個基於給定的標準在此列表中搜索..這裏的標準是在例如等領域的OR和AND操作與各種領域的組合讓我所有的員工,其中:

  • 的firstName =「詹姆斯」 OR「埃裏克」 經理=「Q 「
  • lastname =」bond「「瑪莎」
  • 的firstName =「詹姆斯」 姓=「邦德」 等等...

這將是一個Web API調用,我必須這樣做在一種方法中。另一個挑戰是,每個搜索參數是「可選」,即他們可以通過我firstnames列表和經理的名字而忽略了姓氏參數等,所以這裏是我開始編碼:

public IList<Employee> GetFilteredEmployees(IList<String> firstnames = null, 
               IList<String> lastnames = null, 
               IList<String> managers = null) 
    { 
    if (firstnames != null && firstnames.Any()) 
    { 
      foreach (var fn in firstnames) 
      { 
      employeeByFn = employees.Where(emp => emp.firstName == fn).ToList<Employee>(); 
      } 

     } 

    if (lastnames != null && lastnames.Any()) 
    { 
     foreach (var ln in lastnames) 
     { 
      employeeByLn = employees.Where(emp => emp.LastName == ln).ToList<Employee>(); 
     } 
     } 

    ..... // code ellided 
    } 

由於你可以看到,即使有一些搜索條件參數,這也會變得很難看,在我真正的項目中,我有16個這樣的子查詢,在所有這些子查詢的最後,我必須將我的結果合併到一個員工列表中並返回,請記住,任何子查詢結果可能爲空

我相信這不是一個獨特的問題,我看到類似的問題之前問,但不完全相同的問題。這樣做是這樣的所以如果他們決定在稍後添加更多搜索條件(比如說開始日期),那麼我很容易維護。我希望能夠輕鬆修改我的方法來處理該問題。

感謝一羣尋找。

+1

爲什麼你總是把你的數據填充到一個列表中,然後立即拋出這個列表而不使用它?只需停止爲添加的每個過濾器創建中間列表。 – Servy

回答

5

您可以繼續在相同的結果上添加Where()條件而不是創建許多部分結果。

public IList<Employee> GetFilteredEmployees(IList<String> firstnames = null, 
              IList<String> lastnames = null, 
              IList<String> managers = null) 
{ 
    IQueryable<Employee> result = employees; 

    if (firstnames != null) 
     result = result.Where(emp => firstnames.Contains(emp.firstName)); 

    if (lastnames != null) 
     result = result.Where(emp => lastnames.Contains(emp.LastName)); 

    if (managers != null) 
     result = result.Where(emp => managers.Contains(emp.Manager)); 

    ... // code ellided 

    return result.ToList(); 
} 
+0

錯誤的方法,如果你這樣做的結果將包含dublicate條目,明顯將是必要的! –

+1

@DavitTvildiani這到底會如何重複?每個aditional的'。凡()'返回小於先前的濾波器不多 –

+0

對不起,沒有dublicates但你的過濾器是錯誤的,正確的做法是,在每次啓動過濾整個集合,而不是從以前的查詢查詢過濾結果... 因爲,如果「Klara」不是名字,並且姓氏中包含「bond」,那麼您的過濾器將返回0,當它應該返回... –