2015-07-09 81 views
1

我想在我的整數上使用OR運算符。我可以使用這樣的東西。LINQ自定義OR運算符在SQL服務器上聚合

new int[] { 1, 1, 2, 2, 4, 8, 24, 32, 56 }.Aggregate((a,b) => a | b) 

,等於63.不過,我不能這樣做

db.numbers.Select(a => a.number).Aggregate((a,b) => a | b) 

它拋出該異常:

NotSupportedException異常:LINQ到實體無法識別方法「 Int32 Aggregate [Int32](System.Collections.Generic.IEnumerable 1[System.Int32], System.Func 3 [System.Int32,System.Int32,System.Int32])'方法,並且此方法不能轉換爲存儲表達式。'```

我認爲是因爲它不知道sql server中的什麼函數實現了a | b。我也不知道。

有沒有什麼辦法可以在沒有本地聚合的情況下實現呢?

+1

它不是'|',它是不支持的'Aggregate'。您可以在這裏看到LINQ to Entites中受支持和不受支持的LINQ方法的列表:https://msdn.microsoft.com/en-us/library/vstudio/bb738550(v=vs.100).aspx – MarcinJuraszek

+1

另一個考慮的選擇是編寫一個自定義的.Net聚合函數並將該DLL導入到SQL Server本身。我做了很多這些,他們工作得很好。雖然我不確定如何從LINQ調用它,但如果目標是在SQL方面進行繁重的工作,那麼值得探討。 –

+0

@JosephGagliardo我在挖掘mysql時做了類似的事情,它只是一個用C++編寫的sql函數。但在這種情況下,我必須告訴Linq有一個名爲「mycustomor」的函數,並且最難告訴它是一個聚合函數。但這是一個很好的提及,當事情變得複雜時,我會試驗它。謝謝! –

回答

1

Aggregate不支持linq-to-entities(不管你傳遞什麼函數)。請記住,SQL是基於集合的,所以自定義聚合往往很難翻譯成SQL。

你可以聚集SQL外部:

db.numbers.Select(a => a.number) 
      .AsEnumerable() // shift from EF to Linq-to-Objects 
      .Aggregate((a,b) => a | b) 

的主要區別在於,整個數據集將被拉入內存,而不是聚集的結果。如果你能想出一種方法來做SQL中的聚合(我想不出一種方法),那麼你只需執行一條SQL語句而不是Linq查詢就可以獲得更好的性能。

+0

謝謝,我會接受它(定時器)。 –

+0

我對AsEnumerable或ToList很熟悉,但是它在某些情況下無法在子查詢中工作,比如''db.table.Select(a => db.anothertable.Select(b => b.number).AsEnumerable() .Aggregate((a,b)=> a | b))''''除非你不把AsEnumerable應用到db.table,如果你有很多連接(我有),這可能會很痛苦。從那以後,我會接受這個答案爲否,因爲我在帖子中提到了「沒有在本地彙總」(對於前面提到的情況)。謝謝! –