这是我的第一篇文章,我希望你能帮助我。我没有找到答案,所以我在这里:
我在 SQL 中创建了这个查询并且它有效。
string consultaSQL =
@"SELECT a.GastosEstudio - ISNULL(SUM(b.GastosEstudioR),0) AS restagastos, a.Articulo - ISNULL(SUM(b.ArticuloR),0) AS restaarticulo, a.Honorarios - ISNULL(SUM(b.HonorariosR),0) AS restahonorarios, a.IVAHonorarios - ISNULL(SUM(b.IVAHonorariosR),0) AS restaivahonorarios FROM deudores a LEFT JOIN recibos b ON a.DNI=b.DNI WHERE a.DNI = @DNI GROUP BY a.GastosEstudio, a.Articulo, a.Honorarios, a.IVAHonorarios";
现在我需要在 LINQ 中做同样的事情。基本上:我有两个表(deudores
和recibos
)。在 deudores
中,我欠不同的概念(列):
gastos, articulo, honorarios, ivahonorarios
在表 recibos
中,我插入了具有相同列的收据。
SQL 查询对收据求和并减去债务。我在 LINQ 中得到的最接近的是:
var query = (from d in bd.deudores
join r in bd.recibos on d.DNI equals r.DNI
where d.DNI == DNI
group d by d.DNI into g
select new
{
DNI = g.Key,
articulo = g.Max(x => x.Articulo) - g.Sum(x => x.ArticuloR),
gastos = g.Max(x => x.GastosEstudio) - g.Sum(x => x.GastosEstudioR),
honorarios = g.Max(x => x.Honorarios) - g.Sum(x => x.HonorariosR),
ivah = g.Max(x => x.IVAHonorarios) - g.Sum(x => x.IVAHonorariosR),
});
这个查询的问题是如果没有收据不显示任何信息(应该显示初始债务)
我尝试使用 DefaultIfEmpty
但没有成功:
var query = (from d in bd.deudores
join r in bd.recibos on d.DNI equals r.DNI into Pagos
from p in Pagos.DefaultIfEmpty()
where d.DNI == DNI
group d by d.DNI into g
select new
{
DNI = g.Key,
articulo = g.Max(x => x.Articulo) - g.SelectMany(x => x.recibos).Count() >= 1
? g.SelectMany(x => x.recibos).Sum(y => y.ArticuloR)
: 0,
gastos = g.Max(x => x.GastosEstudio) - g.SelectMany(x => x.recibos).Count() >= 1
? g.SelectMany(x => x.recibos).Sum(y => y.GastosEstudioR)
: 0,
honorarios = g.Max(x => x.Honorarios) - g.SelectMany(x => x.recibos).Count() >= 1
? g.SelectMany(x => x.recibos).Sum(y => y.HonorariosR)
: 0,
ivah = g.Max(x => x.IVAHonorarios) - g.SelectMany(x => x.recibos).Count() >= 1
? g.SelectMany(x => x.recibos).Sum(y => y.IVAHonorariosR)
: 0
});
这个查询的问题是它没有减去它。
有什么建议吗?
谢谢!
最佳答案
你想要一个等价的外连接,所以你正确地转向一个GroupJoin
, or join ... into
.但是查询部分...
from d in bd.deudores
join r in bd.recibos on d.DNI equals r.DNI into Pagos
from p in Pagos.DefaultIfEmpty()
where d.DNI == DNI
group d by d.DNI into g
... 做的比你想的更多。在流利的 LINQ 语法中,它的结构等同于
bd.deudores.GroupJoin(bd.recibos, ...)
.SelectMany(...)
.GroupBy(...)
重点是第一个 GroupJoin
创建了一个 deudores
的集合,每个都有一组 recibos
,可能是空的。然后 SelectMany
将其扁平化为一对 deudores
和一个 recibos
或 null。随后,GroupBy
使用 null
元素创建组。
第一个 GroupJoin
就是您所需要的:
from d in bd.deudores
join r in bd.recibos on d.DNI equals r.DNI into g
select new
{
DNI = d.DNI,
articulo = d.Articulo - g.Select(x => x.ArticuloR).DefaultIfEmpty().Sum(),
gastos = d.GastosEstudio - g.Select(x => x.GastosEstudioR).DefaultIfEmpty().Sum(),
honorarios = d.Honorarios - g.Select(x => x.HonorariosR).DefaultIfEmpty().Sum(),
ivah = d.IVAHonorarios - g.Select(x => x.IVAHonorariosR).DefaultIfEmpty().Sum()
});
通过添加 DefaultIfEmpty()
可以确保 Sum
在没有元素时返回 0。
关于c# - 用linq减去两个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43355377/