将带有嵌套sum的sql查询转换为linq2sql

时间:2012-01-26 22:35:13

标签: c# sql linq-to-sql

我正在尝试将此SQL转换为Linq2SQL查询,但是,我只是将存储过程拖到dbml中,希望有人能做得更好。如果嵌套查询没有记录,则返回null。

SQL:

SELECT
    Table1.Field1 -
    ISNULL(
            (
            SELECT  
                SUM(Table2.Field1) 
            FROM Table2 
                INNER JOIN Table3 ON Table2.ID = Table3.Table2ID 
            WHERE Table3.Table1ID = Table1.ID
            )
            ,0)
FROM
    Table1
WHERE
    (Table1.ID = @ID)

LINQ2SQL

     return (from q in db.Table1s
                    where q.ID == id
                    select q.Field1.GetValueOrDefault() - 
                            (from o in db.Table2s 
                             join r in db.Table3s on o.ID equals r.Table2ID.GetValueOrDefault(0)
                             where r.Table1ID == q.ID
                             select Convert.ToInt32(o.Field1.GetValueOrDefault(0))).Sum()
                    ).SingleOrDefault()

任何人都可以做得更好。

2 个答案:

答案 0 :(得分:2)

使用方法语法和lambda表达式的简明版本:

from t1 in Table1s
select t1.Field1 -  Table3s.Where(x=>x.Table1ID == t1.ID).Sum(y=>y.Table2.Field1)

使用带有let语句的查询语法的更易读的版本:

from t1 in Table1s
let tmp = 
(
    from t3 in Table3s
    where t3.Table1ID == t1.ID
    select t3.Table2.Field1
).Sum()
select t1.Field1 -  tmp

我强烈建议您使用LinqPad之类的工具来设计查询,因为它会向您显示生成的SQL。这使您可以调整更昂贵的查询以获得更好的结果。

它还可用于快速原型设计和短代码块测试。

答案 1 :(得分:1)

这可能会有所帮助: 我会用另一种方式表达sql。像这样:

SELECT
    Table1.Field1 - ISNULL(tblTemp.SumOfField1,0)
FROM
    Table1
    LEFT JOIN
        (
            SELECT  
                SUM(Table2.Field1) AS SumOfField1,
                Table3.Table1ID
            FROM Table2 
                INNER JOIN Table3 ON Table2.ID = Table3.Table2ID 
            GROUP BY 
                Table3.Table1ID
        ) AS tblTemp
        ON tblTemp.Table1ID = Table1.ID
WHERE
    Table1.ID = @ID

然后你的linq代码就像这样(相同的结果只是另一种看待它的方式):

var leftJoin=(
                    from Table2 in db.Table2
                    join Table3 in db.Table3
                        on Table2.ID equals Table3.Table2ID 
                    group Table3 by Table3.Table1ID into g
                    select new
                    {
                        Table1ID=g.Key,
                        SumOf= g.Sum (x =>x.Field1 )
                    }
                );
var output=(
        from Table1 in db.Table1
        from g in leftJoin
            .Where (a =>a.Table1ID==Table1.ID).DefaultIfEmpty()
        select new
        {
            Table1.ID,
            SumOf=(g.SumOf??0)-Table1.Field1
        }
    );