我有以下查询,我想将其翻译为linq。
SELECT
SUM(Credits.CreditAmount)
,Transactions.Id
,Person.FullName
,Person.Id
FROM
Person
JOIN
Transactions
ON Person.AccountId = Transactions.AccountId
JOIN Credits
ON Transactions.Id = Credits.TransactionId
WHERE
Person.Type = 'AccountHolder'
AND Person.Status = 'Active'
AND Transactions.CancelledDate IS NULL
AND Credits.CancelledDate IS NULL
GROUP BY Transactions.AccountId, Person.FullName, Person.Id
HAVING SUM(Credits.CreditAmount) > 20
这就是我想出的。它是一个绝对的猪......它生成的SQL必定是糟糕的。
var query = from p in Person
join t in Transactions
on p.AccountId equalas t.AccountId
join c in Credits
on t.TransactionId = c.TransactionId
where p.Status == "Active" &&
p.Type = "AccountHolder" &&
t.CancelledDate == null &&
c.CancelledDate == null
group new { c.CreditAmount, t.AccountId, p.FullName, p.Id } by new { t.AccountId, p.FullName, p.SSN } into grp
let sumC = grp.Select(x => x.CreditAmount).Sum()
select new
{
TotalCredit = sumC,
AccountId = grp.Key.AccountId,
FullName = grp.Key.FullName,
Id = grp.Key.Id
};
query.Where(p => p.TotalServiceCredit > 20);
SQL查询大约在3秒内运行,但我还没有找到让Linq查询完成的耐心。我想知道是否有一些不同我应该做的事情来完成这个"组,总和,有"查询我试着写?我能做些什么来帮助Linq生成更多的格式化SQL吗?
原来sgmoore有正确的想法。性能问题的关键在于他的回答。
这个
之间的区别let sumC = grp.Select(x => x.CreditAmount).Sum()
和这个
TotalCredit = grp.Sum(x => x.CreditAmount)
是完成的查询与不完成的查询之间的区别。
请参阅下面的修订后的LINQ查询,该查询与SQL几乎同时完成(SQL为5.3秒,LINQ为5.6秒)。
var query = from p in Person
join t in Transactions
on p.AccountId equalas t.AccountId
join c in Credits
on t.TransactionId = c.TransactionId
where p.Status == "Active" &&
p.Type = "AccountHolder" &&
t.CancelledDate == null &&
c.CancelledDate == null
group new { c.CreditAmount, t.AccountId, p.FullName, p.Id } by new { t.AccountId, p.FullName, p.SSN } into grp
select new
{
TotalCredit = grp.Sum(x => x.CreditAmount),
AccountId = grp.Key.AccountId,
FullName = grp.Key.FullName,
Id = grp.Key.Id
};
query.Where(p => p.TotalServiceCredit > 20);
感谢您的帮助!
答案 0 :(得分:2)
我不同意WEI_DBA的评论,但如果您需要这样做,那么您可能会发现将其分解为多个查询更容易,例如
var query1 = from p in Person
join t in Transactions on p.AccountId equals t.AccountId
join c in Credits on t.TransactionId equals c.TransactionId
where p.Status == "Active" &&
p.Type = "AccountHolder" &&
t.CancelledDate == null &&
c.CancelledDate == null
select new { c.CreditAmount, t.AccountID, p.FullName, p.Id};
var query2 = (from p in query1
group p by new { p.AccountId, p.FullName, p.Id } into grp
select new
{
TotalCredit = grp.Sum(x => x.CreditAmount),
AccountId = grp.Key.AccountId,
FullName = grp.Key.FullName,
Id = grp.Key.Id
};
var query3 = (from p in query2 where p.TotalCredit > 20 select p);
然后你可以让LINQ将它组合成一个sql命令。
与往常一样,检查并验证实际生成的TSQL是个好主意。