c# - 用linq减去两个表

标签 c# asp.net linq

这是我的第一篇文章,我希望你能帮助我。我没有找到答案,所以我在这里:

我在 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 中做同样的事情。基本上:我有两个表(deudoresrecibos)。在 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/

相关文章:

ASP.NET 核心 : Prevent Automatic HTTP 400 responses for individual action

c# - Skip 的性能(以及类似的功能,如 Take)

c# - 无效的匿名类型成员声明符 c# linq?

c# - 在哪里可以找到用简码定义的美国所有州的类?

c# - Paypal电子商务网站如何处理多种货币?

c# - 有没有更快的方法让多个文件夹分配图标?如何改进这段代码?

asp.net - Azure 和 Aspnet_regsql.exe

c# - ASP.NET 标识 : Make other fields in AspNetUsers unique key

c# - System.Drawing.dll 中出现类型为 'System.ApplicationException' 的未处理异常

c# - 使用 Lambda 表达式创建自定义列表