针对SQLite数据库的LINQPad查询中的InvalidOperationException

时间:2012-07-11 15:47:29

标签: linq linqpad

我在应用程序中有以下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

1 个答案:

答案 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() 

将起作用,这意味着您不需要将数据存入内存。