如何使用 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 的共同值。
然后对于每个组,保留具有最高值PaymentId
的PaymentHistory
。毕竟: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
【讨论】:
看来&& x.FeePaid != 0
检查可能没有必要。
@Batuhan 为什么? OP 说答案应该是 30.00;没有它,答案将是 0.0以上是关于如何使用 LINQ 获取最新号码的主要内容,如果未能解决你的问题,请参考以下文章