如何使用 LINQ 获取最新号码

Posted

技术标签:

【中文标题】如何使用 LINQ 获取最新号码【英文标题】:How to get the latest number using 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?我们排除零了吗? 【参考方案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

以上是关于如何使用 LINQ 获取最新号码的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET Core Web API 中使用 LINQ 仅从数据库中获取最新的 id?

使用 Linq C# 获取元组对象列表中的最新日期对象

如何使用 LINQ 获取索引? [复制]

如何使用linq获取表中值的计数

如何使用 linq 从集合中获取特定集合?

如何使用 TSQL 而不是 linq 获取和跳过记录 [重复]