【问题标题】:How to increment column with last column value in Lambda or Linq如何在 Lambda 或 Linq 中使用最后一列值增加列
【发布时间】:2014-12-10 21:51:32
【问题描述】:

我不是 Linq 或 Lambda 方面的专家,我确​​实需要有关此查询的帮助。

这就像对帐单一样,它有借方、贷方和余额。但是我的 linq 查询是错误的,我在执行这个查询时得到了这个结果......

结果: 假设结果是这样的。

这是我的代码:

 decimal Balance = 0;
 var result = from a in entities.Payments
              where a.StudentID == ParamStudentID
              select new
              {
                 Date = a.DateAdded,
                 Code = entities.Particulars.Where(p => p.Name == a.PaymentDes).Select(sp => sp.Code).FirstOrDefault(),
                 Particulars = a.PaymentDes,
                 Debit = 0,
                 Credit = a.Amount,
                 Balance = Balance + a.Amount,
                 SyTerm = a.SchoolYear + "-" + a.Term.Trim().Substring(0, 5)
              };

我知道这是一个简单的问题,但我不知道如何解决。 :D 任何人都可以帮助我。

【问题讨论】:

  • 我认为 1322 在所需的结果集中是错误的。不应该是1325吗?
  • @GiorgosBetsos 哦,原谅我..
  • 记录是如何排序的?
  • @GiorgosBetsos 按交易日期排序。先生
  • 您本质上想要的是计算有序结果集的运行总计。看看这里stackoverflow.com/questions/1834753/…

标签: c# linq lambda


【解决方案1】:

希望对你有帮助:

 var result = from a in entities.Payments
          where a.StudentID == ParamStudentID
          select new
          {
             Date = a.DateAdded,
             Code = entities.Particulars.Where(p => p.Name == a.PaymentDes).Select(sp => sp.Code).FirstOrDefault(),
             Particulars = a.PaymentDes,
             Debit = 0,
             Credit = a.Amount,
             Balance = entities.Payments.Where(x => x.StudentID == ParamStudentID).TakeWhile(x => x != a).Sum(x => x.Amount) + a.Amount,
             SyTerm = a.SchoolYear + "-" + a.Term.Trim().Substring(0, 5)
          };

如果我有任何语法错误,我深表歉意,但我是用记事本写的,但你可以明白的:)。

【讨论】:

  • 在上述 linq 查询中如何处理按交易日期排序?
  • @GiorgosBetsos 因为我只是使用了 OP 的代码,我认为我不需要考虑这一点。
【解决方案2】:

当您使用实体框架时,您正在处理限制性更强的 LINQ 版本。 LINQ 是围绕不可变变量设计的。您可以通过在查询之外使用可变变量来解决此问题,但使用 LINQ to Entities 时该选项会消失。

处理它的一种方法是执行相同的查询,然后遍历它并设置余额。

var result = (from a in entities.Payments
             where a.StudentID == ParamStudentID
             orderby a.DateAdded ascending
             select new
             {
                 Date = a.DateAdded,
                 Code = entities.Particulars.Where(p => p.Name == a.PaymentDes).Select(sp => sp.Code).FirstOrDefault(),
                 Particulars = a.PaymentDes,
                 Debit = 0,
                 Credit = a.Amount,
                 Balance = 0,
                 SyTerm = a.SchoolYear + "-" + a.Term.Trim().Substring(0, 5)
              }).ToList();

double balance = 0;

foreach(var item in result)
{
    balance += item.Credit;
    item.Balance = balance;
}

在 LINQ 查询中可能还有其他方法可以完成这一切,但我认为它们可能会相对复杂或使 SQL 非常奇怪。

【讨论】:

  • 问题是余额不在当前上下文中。
  • 这有点改变。您可能想在原始问题中明确说明这一点。
【解决方案3】:
 decimal balance = 0;  //Change for clarity
 var result = (from a in entities.Payments
              where a.StudentID == ParamStudentID
              select new
              {
                 Date = a.DateAdded,
                 Code = entities.Particulars.Where(p => p.Name == a.PaymentDes).Select(sp => sp.Code).FirstOrDefault(),
                 Particulars = a.PaymentDes,
                 Debit = 0,
                 Credit = a.Amount,
                 SyTerm = a.SchoolYear + "-" + a.Term.Trim().Substring(0, 5)
              }).ToList()
                .Select(r=>new 
                   {
                       Rec = r, 
                       Balance = balance += r.Credit
                   });

注意: 这仅在第一次使用查询时有效。您可能应该在查询结束时抛出.ToList(),或者在不重置累加器的情况下不重用它。

【讨论】:

  • Balance is not exist on current context 这是编写代码时的问题,先生。
  • 确实如此。您正在创建一个匿名课程,并且可以随意调用您的财产。另一个余额是您在开始时定义的十进制累加器。我只是给你具体的线路来改变。我已经用你的整个代码片段和我建议的更改更新了我的答案。
  • 当他使用实体框架时,此方法失败。即使将累加器移动到上下文范围内,也会出现表达式树不能包含赋值语句的错误。如果他正在使用 LINQ to Objects,这可以正常工作。但是,它在 LINQ to Entities 中不起作用。
  • 感谢您的澄清。所以可以执行初始查询,调用ToList(),然后可以执行第二次选择来调整结果,并添加累加器。
  • 我已修改查询以解决实体表达式树问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-09
  • 1970-01-01
相关资源
最近更新 更多