2014-01-31 30 views
0

我有一種方法可以在我的數據庫中搜索人員。我想重構它,以便它使用哈希集來提高性能。EF中的HashSet過濾

我在下面做了一個簡化的例子(它不會編譯,只是給你一個想法)。

在我的例子中可以使用HashSet嗎?

using (var context = new MyEntities()) 
{ 
    var persons = new HashSet<PERSON>(context.PERSON); 

    if(!string.IsNullOrEmpty(age)) 
    { 
     persons = persons.Where(p => p.age == age); 
    } 

    if(!string.IsNullOrEmpty(name)) 
    { 
     persons = persons.Where(p => p.name.StartsWith(name)); 
    } 
    //some similar filtering... 

    return persons.ToList(); 
} 
+0

警告!如果人員表格太大,您將耗盡內存,因爲所有人員都將加載到內存中。只需讓數據庫爲您進行過濾。如果查詢速度慢,請檢查您的查詢並使用索引。 – LostInComputer

+0

它可以使用。你有沒有遇到任何問題? – Rezoan

+0

@Rezoan HashSets沒有Where()方法,所以是的,我確實遇到了問題。 – Johan

回答

1

正如在評論中已經指出,下面的代碼行是不是一個好主意

var persons = new HashSet<PERSON>(context.PERSON); 

,因爲它將把所有的數據從PERSONDbSet並將其插入到person對象。

您的代碼幾乎儘可能優化,無需將所有數據讀入HashSet

我建議你建立一個IQueryable對象,它將激發相關的定製Sql來過濾你的數據。直到您撥打電話ToList()

var persons = context.PERSON.AsQueryable(); 

if(!string.IsNullOrEmpty(age)) 
{ 
    persons = persons.Where(p => p.age == age); 
} 

if(!string.IsNullOrEmpty(name)) 
{ 
    persons = persons.Where(p => p.name.StartsWith(name)); 
} 
//some similar filtering... 

return persons.ToList(); 
+1

的答案是的,這就是我正在談論的。 – Rezoan

+0

'.AsQueryable()'和'IQueriable '之間是否有區別?如果我的lambda無法轉換爲SQL,會發生什麼? – Johan

+0

@Johan這兩者之間沒有區別--AsQueryable只是意味着你可以使用'var persons'。如果你有一些過濾器不能被轉換成Sql,那麼你必須在調用ToList()之後應用這些過濾器*。你必須建立一些測試來確定'HashSet'是否對此有利,但我認爲它可能不值得。 – qujck