情況:我有List<IQueryable<MyDataStructure>>
。我想在它們中的每一個上並行運行一個linq查詢,然後加入結果。在多個IQueryable上並行運行相同的linq查詢?
問題:如何創建一個可以作爲參數傳遞的linq查詢?
示例代碼:
這裏的一些簡化的代碼。首先,我有IQueryable<string>
集合:
public List<IQueryable<string>> GetQueries()
{
var set1 = (new List<string> { "hello", "hey" }).AsQueryable();
var set2 = (new List<string> { "cat", "dog", "house" }).AsQueryable();
var set3 = (new List<string> { "cat", "dog", "house" }).AsQueryable();
var set4 = (new List<string> { "hello", "hey" }).AsQueryable();
var sets = new List<IQueryable<string>> { set1, set2, set3, set4 };
return sets;
}
我想找到所有與字母「H」開始的話。使用單一IQueryable<string>
這是很容易:
query.Where(x => x.StartsWith("h")).ToList()
但我想運行對所有並行IQueryable<string>
對象相同的查詢,然後合併結果。這裏有一種方法:
var result = new ConcurrentBag<string>();
Parallel.ForEach(queries, query =>
{
var partOfResult = query.Where(x => x.StartsWith("h")).ToList();
foreach (var word in partOfResult)
{
result.Add(word);
}
});
Console.WriteLine(result.Count);
但我希望這是一個更通用的解決方案。所以我可以單獨定義linq操作並將它作爲參數傳遞給方法。這樣的事情:
var query = Where(x => x.FirstName.StartsWith("d") && x.IsRemoved == false)
.Select(x => x.FirstName)
.OrderBy(x => x.FirstName);
var queries = GetQueries();
var result = Run(queries, query);
但我在如何做到這一點的損失。有任何想法嗎?
這很有趣,但我認爲這個問題的總體思路和查詢的用法是通過構建/生成表達式樹來減少對提供者的調用,這些表達式樹要被**評估/解析/處理你正在運行它/提供者;通過這種方式提供者可以採取這種(可能是複雜的)表達式,並以任何它被認爲是最優化的方式運行它一次。此代碼示例是否實現了這一點? –
@BrettCaswell OPs代碼是LINQ到對象的所有東西,並在內存中處理,所以這不是一個問題。儘管如此,這在內存中起作用 - 所以它不能處理這個問題。 –
感謝您的迴應,我想你是對的..我在想無論是SQL,Entity還是Object ..下劃線概念仍然是構建表達式樹。我看了一下PredicateBuilders和LINQkit,看起來可以創建Expression.Lambda,它使用InvocationExpressions(invoke)來構建QueryExpression。有一個小小的欺騙(交換)與一個EntitySet擴展方法 –