我在应用程序中有以下LINQ查询。数据源是在内存中构造的List<Borehole>
,用于测试目的。
var lq = from p in data
group p by p.CostCenter into g
select new { CostCenter = g.Key,
AverageDepth = g.Average(p => p.OriginalDepth),
NullDepthCount = g.Count(p => p.OriginalDepth == null) };
它完美运行并提供所需的选择结果。但是,当我在LINQPad中运行以下查询时,会产生InvalidOperationException
:
var lq = from p in Boreholes
group p by p.CostCenter into g
select new { CostCenter = g.Key,
AverageDepth = g.Average(p => p.OriginalDepth),
NullDepthCount = g.Count(p => p.OriginalDepth == null) };
此处数据源是SQLite数据库中的表,使用IQ 2.0.5.0 LINQPad驱动程序链接到LINQPad。错误消息是:
No generic method 'Where' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.
我正在使用LINQPad v4.42.01
。应用程序示例与.NET Framework 4 Client Profile
进行编译。
OriginalDepth
属性的类型为double?
。
为什么我的查询在LINQPad中不起作用/为什么它在我的应用程序中工作?
如何修复LINQPad查询?
更新
如果我将我的应用程序代码(包括伪Borehole
类的定义和伪data
列表的创建)复制并粘贴到LINQPad中,它可以正常工作。因此,问题不在于LINQPad拒绝在应用程序中工作的查询格式。
问题变成:为什么我可以在g.Count(p => p.OriginalDepth == null)
对象上使用List<Borehole>
,但是当我在LINQPad访问的SQLite表上执行相同的查询时,我得到{ {1}}如上所述?
更新2
查询的InvalidOperationException
部分的谓词是什么并不重要。当针对SQLite数据库表执行时,以下结果会导致相同的错误:
g.count
答案 0 :(得分:3)
并非每个Linq提供商都会支持所有功能,因此可能您在此处遇到IQ提供商不支持的功能。
如果表的大小很小(通常是sqlite数据库),那么你可以做
var lq = from p in Boreholes.ToList()
group p by p.CostCenter into g
select new { CostCenter = g.Key,
AverageDepth = g.Average(p => p.OriginalDepth),
NullDepthCount = g.Count(p => p.OriginalDepth == null) };
显然,这会将整个钻孔表加载到内存中,因此查询现在是一个Linq To对象查询,然后可以工作。
更新
似乎只是替换
NullDepthCount = g.Count(p => p.OriginalDepth == null)
在原始查询
中 NullDepthCount = g.Where(p => p.OriginalDepth == null).Count()
将起作用,这意味着您不需要将数据存入内存。