0

我在应用程序中有以下 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. 应用程序示例是编译 vs .NET Framework 4 Client Profile

OriginalDepth属性的类型为double?

为什么我的查询在 LINQPad 中不起作用/为什么它在我的应用程序中起作用?

我可以做些什么来修复 LINQPad 查询?

更新

如果我将我的应用程序代码(包括虚拟Borehole类的定义和虚拟data列表的创建)复制并粘贴到 LINQPad 中,它可以正常工作。因此,问题不在于 LINQPad 拒绝在应用程序中工作的查询格式。

问题变成了:为什么我可以g.Count(p => p.OriginalDepth == null)在一个List<Borehole>对象上使用,但是当我对 LINQPad 访问的 SQLite 表执行相同的查询时,我得到InvalidOperationException了如上所述的结果?

更新 2

g.count查询部分的谓词是什么并不重要。当对 SQLite 数据库表执行时,以下结果会导致相同的错误:

var lq2 = from p in Boreholes
          group p by p.CostCenter into g
          select new { NullDepthCount = g.Count(p => true )}; 
4

1 回答 1

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

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

于 2012-07-11T17:57:22.203 回答