2011-07-30 54 views
2

如何使用基於具有非唯一值的屬性的lambda表達式來快速查找大集合的多個值?根據屬性快速從一組中選擇元素

樣品情況下(沒有性能優化):

class Product 
{ 
    public string Title { get; set; } 
    public int Price { get; set; } 
    public string Description { get; set; } 
} 

IList<Product> products = this.LoadProducts(); 

var q1 = products.Where(c => c.Title == "Hello"); // 1 product. 
var q2 = products.Where(c => c.Title == "Sample"); // 5 products. 
var q3 = products.Where(c => string.IsNullOrEmpty(c.Title)); // 12 345 products. 

如果標題是獨一無二的,它會很容易通過使用IDictionaryHashSet以優化性能。但是那些值不是唯一的情況呢?

+0

根據'標題'排序的二叉搜索樹可能(如果這是您需要查找的唯一屬性) – Magnus

+0

您的最後一個查詢不會編譯。你的意思是'string.IsNullOrEmpty(c.Title)'? – svick

+0

@svick:已修改。謝謝。 –

回答

2

最簡單的解決方案是使用Product的集合字典。最簡單的就是使用

var products = this.LoadProducts().ToLookup(p => p.Title); 

var example1 = products["Hello"]; // 1 product 
var example2 = products["Sample"]; // 5 products 

你的第三個例子是有點困難,但你可以使用ApplyResultSelector()了點。

2

您需要的是能夠在LINQ中運行索引查詢。 (與我們在SQL做)

有一個叫i4o的庫,顯然可以解決你的問題:

http://i4o.codeplex.com/

從他們的網站:

i4o的(指數爲對象)是擴展LINQ 的第一個類庫,允許您在對象上放置索引。使用i4o,LINQ操作的速度通常比不使用 i4o的速度快上千倍。

i4o的工作原理是讓開發人員指定的 IndexSpecification任何類,然後使用 IndexableCollection實現這個類的一個集合, 將使用索引規範,而不是順序查找,當 做LINQ操作可以從索引中受益。

還有以下提供瞭如何使用i4o的一個例子:

http://www.hookedonlinq.com/i4o.ashx

長話短說,你需要:

  1. 添加[可轉位()]屬性到你的「標題「屬性
  2. 使用IndexableCollection <產品>作爲您的數據源。
  3. 從這一點來看,任何使用索引字段的linq查詢都將使用該索引而不是執行順序搜索,從而導致使用該索引的查詢的magnituide性能增加順序。
+0

+1不錯。你對這個圖書館有很好的經驗嗎? – sgtz

+0

我還沒有在生產中使用它,但期待這樣做。 –

相關問題