代码之家  ›  专栏  ›  技术社区  ›  Michael Buen

在Linq to SQL上是否可以实现干净的SQL?

  •  3
  • Michael Buen  · 技术社区  · 14 年前

    在linq-to-sql中,是否可以实现干净的(或者我应该说是性能良好的)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 - Left Join, Group By, and Count

    下面是我的代码版本:

    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 回复  |  直到 13 年前
        1
  •  2
  •   shaunmartin    13 年前

    我认为您通常必须接受Linq to SQL生成的内容,但希望Linq to SQL允许您 完全忽略SQL (大多数时间)-我发现这是一个有价值的折衷。

    对于复杂的报表,我通常退出Linq to SQL并编写纯SQL,特别是在查询涉及大量特定于数据库的情况下。 UDF's 诸如此类。