2015-07-09 85 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,如果你有很多连接(我有),这可能会很痛苦。从那以后,我会接受这个答案为否,因为我在帖子中提到了“没有在本地汇总”(对于前面提到的情况)。谢谢! –