Linq2SQL分组和总和优化

时间:2012-03-09 09:07:24

标签: c# sql linq

我现在已经在这个问题上敲了一下头。我想实现这个目标:

SELECT [t2].[nArtKey], [t2].[value] AS [nQty]
FROM (
    SELECT SUM([t0].[nQty]) AS [value], [t1].[nArtKey]
        FROM [vdatStockTransactions] AS [t0]
        INNER JOIN [regArtSKU] AS [t1] ON [t0].[nSKU] = [t1].[nSKU]
        GROUP BY [t1].[nArtKey]
        ) AS [t2]
    INNER JOIN [regArticles] AS [t3] ON [t2].[nArtKey] = [t3].[nArtKey]
    INNER JOIN [regGroupConnector] AS [t4] ON [t2].[nArtKey] = [t4].[nArtKey]
WHERE [t2].[value] > @p0

到目前为止我使用LINQ给了我很多我想要的东西,为数量而烦恼......

from trans in context.vdatStockTransactions
join sku in context.regArtSKUs on trans.nSKU equals sku.nSKU
group trans by new { sku.nArtKey } into grp
where grp.Sum(g => g.nQty) > 0
join art in context.regArticles on grp.Key.nArtKey equals art.nArtKey       
join ca in context.regGroupConnectors on grp.Key.nArtKey equals ca.nArtKey
select new
{
    nArtKey = grp.Key.nArtKey,
    //nQty = grp.Sum(g => g.nQty)
};

但是,如果我取消注释nQty,我会得到这个:

SELECT [t7].[nArtKey], [t7].[value] AS [nQty]
FROM (
    SELECT [t3].[nArtKey], (
        SELECT SUM([t5].[nQty])
        FROM [vdatStockTransactions] AS [t5]
        INNER JOIN [regArtSKU] AS [t6] ON [t5].[nSKU] = [t6].[nSKU]
        WHERE [t2].[nArtKey] = [t6].[nArtKey]
        ) AS [value], [t2].[value] AS [value2]
    FROM (
        SELECT SUM([t0].[nQty]) AS [value], [t1].[nArtKey]
        FROM [vdatStockTransactions] AS [t0]
        INNER JOIN [regArtSKU] AS [t1] ON [t0].[nSKU] = [t1].[nSKU]
        GROUP BY [t1].[nArtKey]
        ) AS [t2]
    INNER JOIN [regArticles] AS [t3] ON [t2].[nArtKey] = [t3].[nArtKey]
    INNER JOIN [regGroupConnector] AS [t4] ON [t2].[nArtKey] = [t4].[nArtKey]
    ) AS [t7]
WHERE [t7].[value2] > @p0

为什么它会创建额外的子查询,是否有任何方法可以避免它?它在性能上有很大的不同,所以我真的很想弄明白。我想要的只是使用数量([t2]。[value])并将其输入SELECT语句。

只有在分组后有多个连接时,才会存在额外的子查询,因此,如果我删除,则查询会生成预期的SQL。

注意:我删除了原始查询,只保留产生此行为的部分,以便更容易理解。

1 个答案:

答案 0 :(得分:0)

我没有对此进行过测试,但这可能会解决问题:

var quantities =
    from trans in context.vdatStockTransactions
    group trans by trans.SKU.nArtKey into grp
    select new
    {
        nQty = grp.Sum(g => g.nQty), 
        nArtKey = grp.Key 
    };

var results =
    from quantity in quantities
    join art in context.regArticles
        on quantity.nArtKey equals art.nArtKey       
    join ca in context.regGroupConnectors 
        on quantity.nArtKey equals ca.nArtKey
    where quantity.nQty > 0
    select quantity;