来自 SQL 查询的复杂 LINQ 查询
我有一个 SQL 查询:
SELECT Sum(ABS([Minimum Installment])) AS SumOfMonthlyPayments FROM tblAccount
INNER JOIN tblAccountOwner ON tblAccount.[Creditor Registry ID] = tblAccountOwner.
[Creditor Registry ID] AND tblAccount.[Account No] = tblAccountOwner.[Account No]
WHERE (tblAccountOwner.[Account Owner Registry ID] = 731752693037116688)
AND (tblAccount.[Account Type] NOT IN ('CA00', 'CA01', 'CA03', 'CA04', 'CA02', 'PA00', 'PA01', 'PA02', 'PA03', 'PA04'))
AND (DATEDIFF(mm, tblAccount.[State Change Date], GETDATE()) <=
6 OR tblAccount.[State Change Date] IS NULL)
AND (tblAccount.[Account Status ID] <> 999)
AND ((tblAccount.[Account Type] NOT IN ('CL01','PL01','CL10','
CL11','PL10','PL11','OD','CL00','PL00','CL03','CL20','CL30','CL31','CL32',
'CL33','CL34','CL35','CL69','CL90','ML00','PL03','PL20','PL30','PL31','PL33',
'CA00', 'CA01', 'CA03', 'CA04', 'CA02', 'PA00', 'PA01', 'PA02', 'PA03', 'PA04',
'PL34','PL35','PL40','PL90'))
AND NOT CONTAINS(tblAccount.[Account Type], 'Overdra')
OR NOT CONTAINS(tblAccount.[Account Type], 'Mortgage')
OR NOT CONTAINS(tblAccount.[Account Type],'Revolv')
OR NOT CONTAINS(tblAccount.[Account Type],'*Credit*Card*'))
我已将其转换为 LINQ:
var excludeTypes = new[]
{
"CA00", "CA01", "CA03", "CA04", "CA02",
"PA00", "PA01", "PA02", "PA03", "PA04"
};
var maxStateChangeMonth = 4;
var excludeStatusId = 999;
var includOtherPayments = new[] {
"CL01","PL01","CL10",
"CL11","PL10","PL11","OD","CL00","PL00","CL03","CL20","CL30",
"CL31","CL32,CL33","CL34","CL35","CL69","CL90","ML00","PL03",
"PL20","PL30","PL31","PL33,CA00", "CA01", "CA03", "CA04","CA02",
"PA00", "PA01", "PA02", "PA03", "PA04,PL34","PL35","PL40","PL90"
};
var sum = (
from account in context.Accounts
from owner in account.AccountOwners
where owner.AccountOwnerRegistryId == ownerRegistryId
where !excludeTypes.Contains(account.AccountType)
where account.StateChangeDate == null
||
EntityFunctions.DiffMonths(account.StateChangeDate, DateTime.Now)
<= maxStateChangeMonth
where includOtherPayments.Contains(account.AccountType) ||
!account.AccountType.Contains("Overdra") || !account.AccountType.Contains("Mortgage")
|| !account.AccountType.Contains("Revolv") || !account.AccountType.Contains("*Credit*Card*")
where account.AccountStatusId != excludeStatusId
select (decimal?)account.MinimumInstallment).ToList()
.Sum(minimumInstallment => Math.Abs((decimal)(minimumInstallment)));
return sum;
但 SQL 返回 0,而 LINq 返回 23456。我知道问题出在 LINQ 中的括号或 where 语句的顺序。请建议我解决方案。
I have an SQL query :
SELECT Sum(ABS([Minimum Installment])) AS SumOfMonthlyPayments FROM tblAccount
INNER JOIN tblAccountOwner ON tblAccount.[Creditor Registry ID] = tblAccountOwner.
[Creditor Registry ID] AND tblAccount.[Account No] = tblAccountOwner.[Account No]
WHERE (tblAccountOwner.[Account Owner Registry ID] = 731752693037116688)
AND (tblAccount.[Account Type] NOT IN ('CA00', 'CA01', 'CA03', 'CA04', 'CA02', 'PA00', 'PA01', 'PA02', 'PA03', 'PA04'))
AND (DATEDIFF(mm, tblAccount.[State Change Date], GETDATE()) <=
6 OR tblAccount.[State Change Date] IS NULL)
AND (tblAccount.[Account Status ID] <> 999)
AND ((tblAccount.[Account Type] NOT IN ('CL01','PL01','CL10','
CL11','PL10','PL11','OD','CL00','PL00','CL03','CL20','CL30','CL31','CL32',
'CL33','CL34','CL35','CL69','CL90','ML00','PL03','PL20','PL30','PL31','PL33',
'CA00', 'CA01', 'CA03', 'CA04', 'CA02', 'PA00', 'PA01', 'PA02', 'PA03', 'PA04',
'PL34','PL35','PL40','PL90'))
AND NOT CONTAINS(tblAccount.[Account Type], 'Overdra')
OR NOT CONTAINS(tblAccount.[Account Type], 'Mortgage')
OR NOT CONTAINS(tblAccount.[Account Type],'Revolv')
OR NOT CONTAINS(tblAccount.[Account Type],'*Credit*Card*'))
I have translated it to LINQ:
var excludeTypes = new[]
{
"CA00", "CA01", "CA03", "CA04", "CA02",
"PA00", "PA01", "PA02", "PA03", "PA04"
};
var maxStateChangeMonth = 4;
var excludeStatusId = 999;
var includOtherPayments = new[] {
"CL01","PL01","CL10",
"CL11","PL10","PL11","OD","CL00","PL00","CL03","CL20","CL30",
"CL31","CL32,CL33","CL34","CL35","CL69","CL90","ML00","PL03",
"PL20","PL30","PL31","PL33,CA00", "CA01", "CA03", "CA04","CA02",
"PA00", "PA01", "PA02", "PA03", "PA04,PL34","PL35","PL40","PL90"
};
var sum = (
from account in context.Accounts
from owner in account.AccountOwners
where owner.AccountOwnerRegistryId == ownerRegistryId
where !excludeTypes.Contains(account.AccountType)
where account.StateChangeDate == null
||
EntityFunctions.DiffMonths(account.StateChangeDate, DateTime.Now)
<= maxStateChangeMonth
where includOtherPayments.Contains(account.AccountType) ||
!account.AccountType.Contains("Overdra") || !account.AccountType.Contains("Mortgage")
|| !account.AccountType.Contains("Revolv") || !account.AccountType.Contains("*Credit*Card*")
where account.AccountStatusId != excludeStatusId
select (decimal?)account.MinimumInstallment).ToList()
.Sum(minimumInstallment => Math.Abs((decimal)(minimumInstallment)));
return sum;
but SQL is returning 0 where as LINq is returning 23456. I know the issue is with paranthesis in LINQ or order of where statements. Please suggest me solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以尝试将 LINQ 查询放入 LINQPad 中。它是一个有用的免费工具,可以向您显示 LINQ 查询生成的原始 SQL,以帮助您调试它。它将适用于 LINQ-to-SQL 和实体框架查询。
You could try putting your LINQ query into LINQPad. It's a useful free tool that'll show you the raw SQL generated by your LINQ query to help you debug it. It'll work with both LINQ-to-SQL and Entity Framework queries.
从第一眼看,主要区别是:
- SQL 查询中的 FTS 函数
包含
- LINQ 查询中的方法
Contains
(被翻译为like
,而不是 FTS 调用)如果您想使用 FTS - 您应该使用表值函数 (TVF) 或存储程序(SP)。还有一些其他选项(例如,ExecuteQuery),但我觉得它们不太方便。
From the first look main difference is:
- FTS function
contains
in SQL query- Method
Contains
in LINQ query (which is translated intolike
, not into FTS call)If you want to use FTS - you should use table valued functions (TVF) or stored procedures (SP). There are some other options (for example, ExecuteQuery), but I don't find them convenient.