Является ли чистый SQL достижимым на Linq to SQL? - PullRequest
3 голосов
/ 24 сентября 2010

Является ли чистый (или я должен сказать, производительный) 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?

1 Ответ

2 голосов
/ 05 февраля 2011

Я думаю, что вам, как правило, приходится мириться с тем, что генерирует LINQ to SQL, но, надеюсь, LINQ to SQL позволит вам полностью игнорировать SQL (большую часть времени) - я считаю, что это ценно компромисс.

Что касается сложных отчетов, я обычно отказываюсь от LINQ to SQL и пишу чистый SQL, особенно когда запрос включает множество специфичных для базы данных UDF и т. П.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...