Given a list IQueryables, how can you sum the count of each, without having multiple statements executed in the database?
return queries
.Sum(qy=> qy.Count());
The above works, but hits the database for each query.
The simple answer is that unless you add the record to the underlying datastore that the Iqueryable is querying, you can't add a new record into an IQueryable. So if you are using LinqToSql then you would have to add a row into the table that the IQueryable was querying in order to "add" a row into the IQueryable.
The IQueryable interface inherits the IEnumerable interface so that if it represents a query, the results of that query can be enumerated. Enumeration causes the expression tree associated with an IQueryable object to be executed. The definition of "executing an expression tree" is specific to a query provider.
How to merge two IQueryable lists in LINQ? By using Concat() Or Union()var filter1 = from p in db. table1 var filter2 = from p in db. table2var filter3 = filter1.
Both IEnumerable and IQueryable are forward collection. Querying data from a database, IEnumerable execute a select query on the server side, load data in-memory on a client-side and then filter data. Querying data from a database, IQueryable execute the select query on the server side with all filters.
You can first use the Aggregate
function with Concat
to combine the IQueryable's and then Count
the total like this:
return queries.Aggregate((x,y) => x.Concat(y)).Count()
Starting from this idea Sum(q1,q2) = q1.Concat(q2).Count()
I've tested the following extensions:
public static class LinqExtensions
{
public static IQueryable<object> ConcatAny<T,R>(this IQueryable<T> q1, IQueryable<R> q2)
{
return q1.Select(c=>(object)null).Concat(q2.Select(c=>(object)null));
}
public static IQueryable<object> ConcatAll(this IEnumerable<IQueryable<object>> queries)
{
var resultQuery = queries.First();
foreach (var query in queries.Skip(1))
{
resultQuery = resultQuery.ConcatAny(query);
}
return resultQuery;
}
}
I assumed you have heterogeneous queries like IQueryable<T>
, IQueryable<R>
so on and you are interested in counting all rows no matter which the source is.
So you might use these extensions like
var q1 = Table1.AsQueryable();
var q2 = Table2.AsQueryable();
var q3 = Table3.AsQueryable();
var queries = new IQueryable<object>[] {q1,q2,q3}; // we use here the covariance feature
return queries.ConcatAll().Count();
The generated SQL might look like this
SELECT COUNT(*) AS [value]
FROM (
SELECT NULL AS [EMPTY]
FROM (
SELECT NULL AS [EMPTY]
FROM [Table1] AS [t0]
UNION ALL
SELECT NULL AS [EMPTY]
FROM [Table2] AS [t1]
) AS [t2]
UNION ALL
SELECT NULL AS [EMPTY]
FROM [Table3] AS [t3]
) AS [t4]
I don't think is very effective though
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With