I have the following LINQ query in an application. The data source is a List<Borehole> constructed in memory for testing purposes.
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) };
It runs perfectly and gives the desired selection result. However, when I run the following query in LINQPad, it results in 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) };
Here the data source is a table in a SQLite database, linked to LINQPad using the IQ 2.0.5.0 LINQPad driver. The error message is:
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.
I’m using LINQPad v4.42.01. The application sample is compiled vs .NET Framework 4 Client Profile.
The OriginalDepth property is of type double?.
Why is my query not working in LINQPad / why is it working in my application?
What can I do to fix the LINQPad query?
UPDATE
If I copy and paste my application code, including the definition of the dummy Borehole class and the creation of the dummy data list, into LINQPad, it works fine. Thus the issue is not that LINQPad rejects a query format that works in an application.
The question becomes: Why can I use g.Count(p => p.OriginalDepth == null) on a List<Borehole> object, but when I do the same query on the SQLite table accessed by LINQPad, I get InvalidOperationException as described above?
UPDATE 2
It doesn’t matter what the predicate for the g.count part of the query is. The following results in the same error, when executed against the SQLite database table:
var lq2 = from p in Boreholes
group p by p.CostCenter into g
select new { NullDepthCount = g.Count(p => true )};
Not every Linq provider is going to support every feature, so presumably you have hit on one here that the IQ provider does not support.
If the size of the table is small (and sqlite databases usually are) then you can do
Obviously this loads the whole of the boreholes table into memory and hence the query is now a Linq To objects query which then works.
Update.
It would also appear that simply replacing
in your original query which
will work which means you don’t need to bring the data into memory.