[英]LINQ to Sql Left Outer Join with Group By and Having Clause
I lost a day to try translate a sql query to LINQ lambda expression but not success. 我失去了一天尝试将SQL查询转换为LINQ lambda表达式,但没有成功。
My sql query: 我的SQL查询:
SELECT a.ID,
Sum(b.[Value]) AS [Value],
c.ContractValue
FROM Contracts a
LEFT JOIN DepositHistories b
ON b.ContractID = a.ID
INNER JOIN LearningPackages c
ON a.LearningPackageID = c.ID
GROUP BY a.ID,
c.ContractValue
HAVING Sum(b.[Value]) < c.ContractValue
OR Sum(b.[Value]) IS NULL
OR Sum(b.[Value]) = 0
This is LINQ query: 这是LINQ查询:
var contracts = (
from a in db.Contracts
from b in db.LearningPackages.Where(e => e.ID == a.LearningPackageID).DefaultIfEmpty()
group a by new
{
a.ID,
b.ContractValue
} into g
from c in db.DepositHistories.Where(e => e.ContractID == g.Key.ID).DefaultIfEmpty()
where g.Sum(e => c.Value) < g.Key.ContractValue || g.Sum(e => c.Value) == null
select new
{
ID = g.Key.ID,
ContractValue = g.Key.ContractValue,
Value = g.Sum(e => c.Value != null ? c.Value : 0)
}
).ToList();
My result: 我的结果:
ID ContractValue Value
1 6000000 500000
1 6000000 500000
1 6000000 500000
1 6000000 500000
1 6000000 500000
3 7000000 500000
3 7000000 500000
3 7000000 500000
4 6000000 500000
5 6000000 0
6 6000000 0
It's not group and sum the values. 它不是组合并对值进行求和。
Please help me! 请帮我!
Thanks! 谢谢!
you can do it like this: 你可以这样做:
var result = from b in db.DepositHistories
join a in db.Contracts on b.CotractID equals a.ID
join c in db.LearningPackages on a.LearningPackageID equals c.ID
group b by new{ a.ID,c.COntractValue} into g
where g.Sum(x=>x.Value) < g.Key.COntractValue
|| g.Sum(x=>x.Value) == null
|| g.Sum(x=>x.Value) == 0
select new
{
ID = g.Key.ID,
Value = g.Sum(x=>x.Value),
ContractValue = g.Key.COntractValue
};
I made a DEMO FIDDLE to be more clear. 我做了一个DEMO FIDDLE来更清楚。
For left outer join you have to do join your condition into somealias
and them from alias in somealias.DefaultIfEmpty()
. 对于左外连接,您必须将
join your condition into somealias
,并将它们from alias in somealias.DefaultIfEmpty()
。
Here is the version with left outer join which gives correct results: 这是左外连接的版本,它给出了正确的结果:
var result = from a in Contracts
join b in DepositHistories on a.ID equals b.CotractID into e
from f in e.DefaultIfEmpty()
join c in LearningPackages on a.LearningPackageID equals c.ID
group f by new
{
a.ID,
c.COntractValue
} into g
where g.Sum(x => x==null ? 0 : x.Value) < g.Key.COntractValue
|| g.Sum(x => x==null ? 0 : x.Value) == 0
select new
{
ID = g.Key.ID,
Value = g.Sum(x => x == null ? 0 : x.Value),
ContractValue = g.Key.COntractValue
};
UPDATED FIDDLE DEMO 更新的FIDDLE演示
You can also check this SO post about How to do left outer join in LINQ 您还可以查看有关如何在LINQ中执行左外连接的SO帖子
Using query method you have to use GroupJoin() method for left outer join. 使用查询方法,您必须使用GroupJoin()方法进行左外连接。
Here is the above code with Method Query: 以下是使用Method Query的上述代码:
var Result = Contracts.GroupJoin(DepositHistories,
a => a.ID,
b => b.CotractID,
(a, b) => new { a = a, b = b })
.Join(LearningPackages,
a => a.a.LearningPackageID,
b => b.ID,
(a, b) => new { a = a, b = b })
.GroupBy(e => new
{
e.a.a.ID,
e.b.COntractValue
},
(k, g) => new
{
ID = k.ID,
ContractValue = k.COntractValue,
Value = g.Sum(x => x == null ? 0 : x.a.b.Sum(d=>d.Value))
}
).Where(x => x.Value < x.ContractValue || x.Value == 0).ToList();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.