【发布时间】:2018-06-12 15:59:24
【问题描述】:
我在 Windows 上使用 EF 6、ASP.NET
我有如下 SQL 语句:
SELECT M.STMTDT, M.stmtno, ISNULL(SUM(M.PayAmount),0) as Fee, ISNULL(SUM(A.Amount),0) as Adjustment, ISNULL(SUM(M.PayAmount) + SUM(A.Amount),0) as Total FROM MainData M
LEFT OUTER JOIN Adjustments A
ON M.STMTDT = A.STMTDT AND M.stmtno = A.Stmtno
where M.CID= '334R' AND YEAR(M.stmtdt) > year(getdate())-4
GROUP BY M.STMTDT, M.stmtno
这是一个非常标准的查询,包含组、连接、位置和总和。我想在 LINQ 中创建相同的查询,但事实证明这样做很困难。
这是我的 LINQ 查询:
var fourYearsAgo = DateTime.Now.AddYears(-4).Year;
var dataWithoutGrouping = from m in MainData
where m.CID == "334r" && m.STMTDT.Value.Year > fourYearsAgo
join a in Adjustments
on new {m.STMTDT, m.Stmtno} equals new {a.STMTDT, a.Stmtno} into grp
from ja in grp.DefaultIfEmpty()
select new {
Dt = m.STMTDT,
No = m.Stmtno,
Fee = m.PayAmount,
Adjustment = ja.Amount
};
var data = (from b in dataWithoutGrouping
group b by new {b.Dt, b.No }into grp
select new {
StatmentFee = grp.Sum(x => x.Fee),
StatementAdjustments = grp.Sum(x => x.Adjustment),
StatementDate = grp.FirstOrDefault().Dt,
StatementNo = grp.FirstOrDefault().No
}).ToList();
产生这个 SQL:
-- Region Parameters
DECLARE @p0 VarChar(1000) = '334r'
DECLARE @p1 Int = 2014
-- EndRegion
SELECT [t3].[value] AS [StatmentFee], [t3].[value2] AS [StatementAdjustments], (
SELECT [t6].[STMTDT]
FROM (
SELECT TOP (1) [t4].[STMTDT]
FROM [MainData] AS [t4]
LEFT OUTER JOIN [Adjustments] AS [t5] ON ([t4].[STMTDT] = [t5].[STMTDT]) AND ([t4].[stmtno] = [t5].[Stmtno])
WHERE ((([t3].[STMTDT] IS NULL) AND ([t4].[STMTDT] IS NULL)) OR (([t3].[STMTDT] IS NOT NULL) AND ([t4].[STMTDT] IS NOT NULL) AND ((([t3].[STMTDT] IS NULL) AND ([t4].[STMTDT] IS NULL)) OR (([t3].[STMTDT] IS NOT NULL) AND ([t4].[STMTDT] IS NOT NULL) AND ([t3].[STMTDT] = [t4].[STMTDT]))))) AND ((([t3].[stmtno] IS NULL) AND ([t4].[stmtno] IS NULL)) OR (([t3].[stmtno] IS NOT NULL) AND ([t4].[stmtno] IS NOT NULL) AND ((([t3].[stmtno] IS NULL) AND ([t4].[stmtno] IS NULL)) OR (([t3].[stmtno] IS NOT NULL) AND ([t4].[stmtno] IS NOT NULL) AND ([t3].[stmtno] = [t4].[stmtno]))))) AND ([t4].[CID] = @p0) AND (DATEPART(Year, [t4].[STMTDT]) > @p1)
) AS [t6]
) AS [StatementDate], (
SELECT [t9].[stmtno]
FROM (
SELECT TOP (1) [t7].[stmtno]
FROM [MainData] AS [t7]
LEFT OUTER JOIN [Adjustments] AS [t8] ON ([t7].[STMTDT] = [t8].[STMTDT]) AND ([t7].[stmtno] = [t8].[Stmtno])
WHERE ((([t3].[STMTDT] IS NULL) AND ([t7].[STMTDT] IS NULL)) OR (([t3].[STMTDT] IS NOT NULL) AND ([t7].[STMTDT] IS NOT NULL) AND ((([t3].[STMTDT] IS NULL) AND ([t7].[STMTDT] IS NULL)) OR (([t3].[STMTDT] IS NOT NULL) AND ([t7].[STMTDT] IS NOT NULL) AND ([t3].[STMTDT] = [t7].[STMTDT]))))) AND ((([t3].[stmtno] IS NULL) AND ([t7].[stmtno] IS NULL)) OR (([t3].[stmtno] IS NOT NULL) AND ([t7].[stmtno] IS NOT NULL) AND ((([t3].[stmtno] IS NULL) AND ([t7].[stmtno] IS NULL)) OR (([t3].[stmtno] IS NOT NULL) AND ([t7].[stmtno] IS NOT NULL) AND ([t3].[stmtno] = [t7].[stmtno]))))) AND ([t7].[CID] = @p0) AND (DATEPART(Year, [t7].[STMTDT]) > @p1)
) AS [t9]
) AS [StatementNo]
FROM (
SELECT SUM([t2].[PayAmount]) AS [value], SUM([t2].[value]) AS [value2], [t2].[STMTDT], [t2].[stmtno]
FROM (
SELECT [t0].[STMTDT], [t0].[stmtno], [t0].[PayAmount], [t1].[Amount] AS [value], [t0].[CID]
FROM [MainData] AS [t0]
LEFT OUTER JOIN [Adjustments] AS [t1] ON ([t0].[STMTDT] = [t1].[STMTDT]) AND ([t0].[stmtno] = [t1].[Stmtno])
) AS [t2]
WHERE ([t2].[CID] = @p0) AND (DATEPART(Year, [t2].[STMTDT]) > @p1)
GROUP BY [t2].[STMTDT], [t2].[stmtno]
) AS [t3]
如您所见,与原始语句相比,此 SQL 效率极低。
请有人帮我转换我的 LINQ 以生成上面显示的原始 SQL。
另外,不,我无法使用 SQL,原因不明,抱歉!
编辑
示例数据:
主要数据:
StmtDate| |StmtNo |费用
2016-01-29| 00:00:00.000 |3124360 |25.00
2016-02-12| 00:00:00.000 |3124391 |50.00
2016-01-29| 00:00:00.000 |3124360 |600.00
2016-02-12| 00:00:00.000 |3124391 |75.00
调整:
StmtDate |站号|调整
2016-01-29 |00:00:00.000 |3124360 0.00
2016-02-12 |00:00:00.000 |3124391 0.00
2016-01-29 |00:00:00.000 |3124360 120.00
2016-02-12 |00:00:00.000 |3124391 60.00
想要的结果:
StmtDate | StmtNo |费用 |调整 |总计
2016-01-29 00:00:00.000 |3124360 |25.00 |0.00 |0.00
2016-02-12 00:00:00.000 |3124391 |50.00 |0.00 |0.00
2016-02-19 00:00:00.000 |3124404 |600.00 |120.00 |720.00
2016-02-19 00:00:00.000 |3124405 |75.00 |60.00 |135.00
【问题讨论】:
-
您使用什么框架(ORM)将 linq 转换为 sql?
-
实体框架
-
什么版本的 EF?什么平台?什么操作系统?
-
EF 6、ASP.NET、Windows
-
您可以在VB.Net中将key命名为:
Group b By New With Keys = {Key b.Dt, Key b.No } into Group,然后引用Keys.Dt和Keys.No。
标签: c# asp.net sql-server entity-framework linq