上下文:我有一个应用程序,允许用户处理当天收到的所有邮寄付款。有时,一个信封可能包含同一个帐户的多张支票(想想两个室友各自支付他们的一部分水电费)。
限制:以 10 个批次处理所有付款,但每批次的帐户 ID 必须是唯一的。
非常简化的支付类:
public class Payment
{
public int AccountId { get; set; }
// ... other properties not important
}
今天通过邮件收到的假设付款。请注意,最后两个 AccountId 值是可接受的重复项:
List<Payment> payments = new List<Payment>()
{
new Payment() {AccountId = 1 },
new Payment() {AccountId = 2 },
new Payment() {AccountId = 3 },
new Payment() {AccountId = 4 },
new Payment() {AccountId = 5 },
new Payment() {AccountId = 1 }, // Duplicate Account
new Payment() {AccountId = 2 } // Duplicate Account
// likely hundreds more unique accounts, possibly even some more duplicates...
};
我正在使用 MoreLinq 尝试为每批选择不同的帐户,但下面的代码显然不起作用。我觉得我已经很接近了,但一直找不到可行的解决方案。同样,目标是将所有付款分成 N 个批次,而不复制该批次中的 AccountId。重复的 AccountId 必须分布在其他批次中,以便在尝试更新客户的余额时不会导致竞争条件。
为清楚起见,编辑了代码注释。
int batchSize = 10;
var paymentTasks = new List<Task>(batchSize);
// This linq expression is the heart of my question: How to divide the payments
// into batches while ensuring uniqueness of a particular key(s). This expression
// is close, but the DistinctBy() is obviously excluding the duplicates that
// I just intend to be distinct for that Batch(batchSize).
foreach (IEnumerable<Payment> batchOfPayments in payments.DistinctBy(a => a.AccountId).Batch(batchSize))
{
// The rest of this method is for context only
paymentTasks.Clear();
foreach (Payment payment in batchOfPayments)
{
// Async method implementation not important
Task paymentTask = ProcessPaymentAsync(payment);
paymentTasks.Add(paymentTask);
}
// Await all the tasks in this batch to complete before starting the next batch
await Task.WhenAll(paymentTasks);
}
感谢您抽出宝贵时间查看我的问题。