Является ли чистый (или я должен сказать, производительный) SQL достижимым в Linq to Sql?
Я хотел, чтобы Linq to Sql произвел этот код:
SELECT C.CustomerID, COUNT(O.CustomerID) AS N
FROM Customers C
LEFT JOIN Orders O ON O.CustomerID = C.CustomerID
GROUP BY C.CustomerID
И я следую этому коду: LINQ - Левое объединение, Группировка по и Количество
Итак, вот моя версия кода:
var q = from c in db.Customers
join o in db.Orders on c.CustomerID equals o.CustomerID into sr
from x in sr.DefaultIfEmpty()
group x by c.CustomerID into y
select new { y.Key, N = y.Count(t => t.CustomerID != null) };
Но это порождает это ...
SELECT [t2].[CustomerID] AS [Key], (
SELECT COUNT(*)
FROM [Customers] AS [t3]
LEFT OUTER JOIN [Orders] AS [t4] ON [t3].[CustomerID] = [t4].[CustomerID]
WHERE ([t4].[CustomerID] IS NOT NULL) AND ((([t2].[CustomerID] IS NULL) AND ([t3].[CustomerID] IS NULL)) OR (([t2].[CustomerID] IS NOT NULL) AND ([t3].[CustomerID] IS NOT NULL) AND ([t2].[CustomerID] = [t3].[CustomerID])))
) AS [N]
FROM (
SELECT [t0].[CustomerID]
FROM [Customers] AS [t0]
LEFT OUTER JOIN [Orders] AS [t1] ON [t0].[CustomerID] = [t1].[CustomerID]
GROUP BY [t0].[CustomerID]
) AS [t2]
... Что я считаю неприемлемым.
Тогда я попробую это ...
var q = from c in db.Customers
join o in db.Orders on c.CustomerID equals o.CustomerID into sr
from x in sr.DefaultIfEmpty()
group x by c.CustomerID into y
select new { y.Key, N = y.Sum(t => t.CustomerID != null ? 1 : 0 )};
... и вот результирующий запрос:
SELECT SUM(
(CASE
WHEN [t1].[CustomerID] IS NOT NULL THEN @p0
ELSE @p1
END)) AS [N], [t0].[CustomerID] AS [Key]
FROM [Customers] AS [t0]
LEFT OUTER JOIN [Orders] AS [t1] ON [t0].[CustomerID] = [t1].[CustomerID]
GROUP BY [t0].[CustomerID]
Хоть и немного чище и выглядит более качественно, но все же не так лаконично и качественно по сравнению с более простым утверждением: COUNT(O.CustomerID)
Возможно ли то, что я пытаюсь сделать, в Linq to SQL?
Как насчет других ORM? в частности, NHibernate, может ли он перевести оператор HQL в свой реальный SQL?