【发布时间】:2018-08-06 02:54:42
【问题描述】:
我目前正在重做一些包含大量查询工作的 LOB 应用程序。
最初是一个 lightswitch vb.net 项目,但由于我想学习 C# 并将新版本基于当前技术,它现在是一个 ASP.Net Core 2.0 项目。
无论如何,我正在尝试将此查询 (VB.Net) 迁移到 C#:
Return From x In _DB
Where x.Amount<> 0
Group By x.str1, x.str2 Into Sum(x.Amount)
Where Sum < 0
Select New Object With {...}
我把它翻译成这样的:
from x in _DB
where x.Amount!= 0
group x by new { x.str1, x.str2} into GROUP
where GROUP.Sum(s => s.Amount) < 0
select new Model()
{
...
}
输出是正确的,我在较小的查询中使用它,但在大约 1.000.000 行的表中,性能差异很大。 VB:3 秒,C#:45 秒。
C# 中的“group into sum”是否有更好的翻译,或者性能问题可能出在其他地方?
编辑:
所以我尝试使用 Linqpad 分析这两个版本,令我惊讶的是,它们的性能或多或少都相同,并且它们都转换为相同的 SQL:
DECLARE @p0 Decimal(21,20) = 0
DECLARE @p1 Decimal(21,20) = 0
SELECT [t1].[Artikelnr_] AS [Artikelnummer], [t1].[Lagerortcode], [t1].
[value2] AS [Bestand]
FROM (
SELECT SUM([t0].[Menge]) AS [value], SUM([t0].[Menge]) AS [value2], [t0].
[Artikelnr_], [t0].[Lagerortcode]
FROM [DB$Artikelposten] AS [t0]
WHERE [t0].[Menge] <> @p0
GROUP BY [t0].[Artikelnr_], [t0].[Lagerortcode]
) AS [t1]
WHERE [t1].[value] < @p1
这很奇怪。也许.net CORE 2.0解释器的问题更多?由于显而易见的原因,我无法使用 vb.net (;
【问题讨论】:
-
您是否使用分析器查看实际生成的查询?这是一个巨大的差异......看起来 c# 版本正在将所有数据带回并在内存中进行分组。
-
你试过 lambda 版本吗(我个人更喜欢这个...)
_DB.Where(x=>x.Amount != 0).GroupBy(x=>new{x.str1, x.str2).Where(g=>g.Sum(s=>s.Amount) < 0).Select(x=> new Model(){...}) -
@GPW 在您的
GroupBy中缺少一个右波浪括号。 -
@smnnekho 看起来您的两个分组属性是字符串,因为它们被命名为
x.strN,因此您可以将它们连接起来并将其用作分组键,而不是创建匿名对象。即:group x by x.str1 + x.str2 into GROUP -
_DB到底是什么?只是为了确保您使用 IQueryable 来执行此任务,您可以创建一个像这样的变量:IQueryable<MyDbTable> dbQueryable = _DB;,然后在您的 linq 查询中使用dbQueryable?
标签: c# vb.net linq asp.net-core .net-core