这是我的第一篇文章,希望你能帮助我。我没有找到答案,所以我在这里:
我在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
});
此查询的问题在于它不会减去它。
有什么建议吗?
谢谢!
答案 0 :(得分:1)
您希望等效于外部联接,因此您可以正确转向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。
答案 1 :(得分:0)
@Gert Arnold:两个表之间的关系是列名DNI
。在表deudores
中是PK,表recibos
中是FK。昨晚我尝试了这段代码并且有效:
var query = (from d in bd.deudores
join r in bd.recibos
on d.DNI equals r.DNI into g
where d.DNI == DNI
select new
{
articulo = d.Articulo - g.Sum(x => x.ArticuloR) ?? d.Articulo,
gastos = d.GastosEstudio - g.Sum(x => x.GastosEstudioR) ?? d.GastosEstudio,
honorarios = d.Honorarios - g.Sum(x => x.HonorariosR) ?? d.Honorarios,
ivah = d.IVAHonorarios - g.Sum(x => x.IVAHonorariosR) ?? d.IVAHonorarios
});
这是最好的方法吗?如果你想给我你的意见,欢迎你。
问候!