【问题标题】:How to get the latest number using LINQ如何使用 LINQ 获取最新号码
【发布时间】:2021-12-07 04:55:08
【问题描述】:

这里在 db 表中列出了客户的付款历史记录

CustomerId  PayId   FeePaid
xx-yy-zz    37      0
xx-yy-zz    32      0
xx-yy-zz    31      30.00
xx-yy-zz    28      0
xx-yy-zz    26      0
xx-yy-zz    18      35.99
xx-yy-zz    17      0
xx-yy-zz    16      0
xx-yy-zz    9       12.00
xx-yy-zz    6       0

PaymentId 列会自动递增。 如何获得该客户的最后一笔付款,即数字 $30.00? 我的项目是 Asp.net API,所以我需要使用 LINQ 来获取号码。

【问题讨论】:

  • 定义“最新”; PayId 是一个单调递增的数字(自动生成并不意味着“单调递增”);为什么不是答案0?我们排除零了吗?

标签: c# asp.net database linq


【解决方案1】:

你写道:

PaymentId 列自动递增

我的建议是将PaymentHistories 分组为每个用户,因此按 CustomerId 的共同值。

然后对于每个组,保留具有最高值PaymentIdPaymentHistory。毕竟:PaymentId 是自动递增的,所以客户 X 的 PaymentHistories 组中的 PaymentHistory 是 PaymentId 最高的那个

为此,我使用了具有参数 resultSelector 的 Queryable.GroupBy 的重载,因此我可以精确地指定我想要的结果。

IQueryable<PaymentHistory> paymentHistories = ...
var lastCustomerPayments = paymentHistories.GroupBy(

    // parameter keySelector: make groups with same CustomerId
    paymentHistory => paymentHistory.CustomerId,

    // parameter resultSelector: for every CustomerId and all PaymentHistories
    // that have this value for CustomerId, make one new:
    (customerId, paymentHistoriesWithThisCustomerId) => new
    {
        CustomerId = customerId,

        // get the feePaid of the PaymentHistory with the largest PaymentId
        FeePaid = paymentHistoriesWithThisCustomerId
            .OrderByDescending(paymentHistory => paymentHistory.PaymentId)
            .Select(paymentHistory => paymentHistory.FeePaid)
            .FirstOrDefault(),
    }

如果不想要 FeePaid,还想要 PaymentId,请使用以下 resultSelector:

(customerId, paymentHistoriesWithThisCustomerId) => new
{
    CustomerId = customerId,

    LastPayment = paymentHistoriesWithThisCustomerId
        .OrderByDescending(paymentHistory => paymentHistory.PaymentId)
        .Select(paymentHistory => new
        {
            PaymentId = paymentHistory.PaymentId,
            FeePaid = paymentHistory.FeePaid,
        })
        .FirstOrDefault();
    }

【讨论】:

    【解决方案2】:

    试试这个 linq 表达式:

    var result = await (from d in _ctx.MyTable
                        where d.CustomerId="xx-yy-zz" && d.FreePaid > 0
                        orderby d.PayId descending
                        select d.FreePaid).FirstOrDefaultAsync();
    
    • 尽量避免否定查询
    • 等待函数

    【讨论】:

      【解决方案3】:

      如果我们假设我们忽略零,并且PayId 是单调递增的,那么大概:

      作为 LINQ:

      var val = ctx.SomeTable
          .Where(x => x.CustomerId == customerId && x.FeePaid != 0)
          .OrderByDescending(x => x.PayId)
          .Select(x => x.FeePaid)
          .First();
      

      或作为 SQL:

      select top 1 FeePaid
      from SomeTable
      where CustomerId = @customerId
      and FeePaid <> 0
      order by PayId desc
      

      【讨论】:

      • 看来&amp;&amp; x.FeePaid != 0检查可能没有必要。
      • @Batuhan 为什么? OP 说答案应该是 30.00;没有它,答案将是 0.0
      猜你喜欢
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      • 1970-01-01
      • 2010-09-23
      • 2011-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多