> Hello,
>
[quoted text clipped - 25 lines]
> Thanks,
> Miguel
Please, anyone?
Thank You,
Miguel
Marc Gravell - 04 Mar 2008 05:29 GMT
If I understand correctly, and using Northwind as a (hopefully similar
example), how about the below; note that it only does a single SQL
query (because we force the ToArray()), but to be honest, I wouldn't
shy away from 2 simpler selects - one for just the total Count(), and
one for the Count() with a Where()... anyway, see how this goes:
var data = ctx.Customers.GroupBy(
cust => cust.CustomerCustomerDemos.Any() ||
cust.Orders.Any())
.Select(grp => new { Linked = grp.Key, Count =
grp.Count() }).ToArray();
foreach (var row in data)
{
Console.WriteLine("{0}: {1}", row.Linked,
row.Count);
}
Console.WriteLine("Total: {0}",
data.Sum(row=>row.Count));
There might be some other options... I'll see if anything occurs...
Marc
Marc Gravell - 04 Mar 2008 07:56 GMT
I found a better answer; the tricky part was getting
deferred execution, as normally Count() executes immediately.
(of course, you could just do 2 simple queries? one Count(),
one Where().Count())
I've approached this instead by using a projection from the
primary table, and used FirstOrDefault, which means that
even if there are no rows, an object with 0 in both counts
is returned.
Aside: note that the .Count(predicate) [even with the Expression
form] does a very funky looking query, hence the simpler
.Where(predicate).Count() usage.
Anyway, the C# is:
var counts = ctx.Customers.Select(x =>
new
{
Total = ctx.Customers.Count(),
Linked = ctx.Customers.Where(
cust => cust.CustomerCustomerDemos.Any()
|| cust.Orders.Any()).Count()
}).FirstOrDefault();
With the faitly reasonable-looking generated SQL:
SELECT TOP (1) [t5].[value] AS [Total], [t5].[value2] AS [Linked]
FROM (
SELECT (
SELECT COUNT(*)
FROM [dbo].[Customers] AS [t1]
) AS [value], (
SELECT COUNT(*)
FROM [dbo].[Customers] AS [t2]
WHERE (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[CustomerCustomerDemo] AS [t3]
WHERE [t3].[CustomerID] = [t2].[CustomerID]
)) OR (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[Orders] AS [t4]
WHERE [t4].[CustomerID] = [t2].[CustomerID]
))
) AS [value2]
FROM [dbo].[Customers] AS [t0]
) AS [t5]
I have looked at the query plan/IO, and it isn't doing anything /too/ crazy.