У меня есть 2 списка с этой структурой:
public class DepositAssembly
{
public string VoucherNo { get; set; }
public string Total { get; set; }
}
public class MpesaAssembly
{
public string ReceiptNo { get; set; }
public double PaidIn { get; set; }
}
Сбор депозитов вводится в систему ERP. Mpesa создается из файла .csv, чтобы обеспечить выполнение платежей.
Я хочу сравнить 2 списка, чтобы убедиться, что: 1. Все ваучеры / квитанции в DepositAssembly находятся в MpesaAssembly. Если нет, покажите ошибку. 2. Что у ваучеров, которые соответствуют, есть та же самая точная сумма, если суммы отличаются, показывают ошибку.
E.g. DepositAssembly VoucherNo Total
icdiihiasi GBP 5,319.39
uhuixjisdjodvo GBP 4,790.73
MpesaAssembly ReceiptNo PaidIn
icdiihiasi 5,319.39
uhuixjisdjodvo 4,790.73
Выше должно пройти
DepositAssembly VoucherNo Total
icdiihiasii GBP 5,319.39
uhuixjisdjodvo GBP 4,790.73
MpesaAssembly ReceiptNo PaidIn
icdiihiasi 5,319.39
uhuixjisdjodvo 4,790.73
Выше должен быть сбой на 1-й номер ваучера, поскольку он не может быть найден в Mpesa .csv
DepositAssembly VoucherNo Total
icdiihiasi GBP 5,319.39
uhuixjisdjodvo GBP 4,790.73
MpesaAssembly ReceiptNo PaidIn
icdiihiasi 5,319.39
uhuixjisdjodvo 4,800.73
Выше должен сбой на uhuixjisdjodvo чек номер PaidIn, так как он не совпадает с номером в DepositAssembly.
Любая функция linq, чтобы сделать это?
У меня есть
var requestWithMatches = from req in depositAssembly
join resp in mpesaAssembly
on req.VoucherNo equals resp.ReceiptNo
select new CallPair(req, resp);
Но это не заботиться о суммах. Необходимо сопоставить как ваучеры, так и суммы.
Как мне проверить, что номер ваучера и итоги существуют точно так же, как в сборке Mpesa? Пример Linq?
2 ответа
Предполагая наличие следующих коллекций:
Deposits
: сбор депозитовReceipts
: записи из вашего .csv файлаDepositsxReceipts
: результат объединенияDeposits
иReceipts
вDeposit.VoucherNo
иReceipt.ReceiptNo
и выбора соединенных пар(deposit, receipt)
Я опишу, как вы можете архивировать ваши цели:
- Все ваучеры / квитанции в DepositAssembly находятся в MpesaAssembly. Если нет, покажите ошибку.
Убедитесь, что DepositsxReceipts.Length
равен Deposits.Length
. На самом деле, здесь мало что происходит. В зависимости от того, сколько информации вы хотите иметь о несоответствующих парах, вам нужно будет использовать форму внешнего соединения.
- То, что соответствующие ваучеры имеют одинаковую точную сумму, если суммы разные, показывают ошибку.
Убедитесь, что для каждой пары (deposit, receipt)
в DepositsxReceipts
выполнено условие deposit.Amount == receipt.Total
.
Ваша вторая цель оставляет простор для пары идей
Учитывая простое LINQ to objects , вы можете сделать следующее:
var depositsxReceipts = from deposit in deposits
join receipt in receipts
on deposit.VoucherNo equals receipt.ReceiptNo
select new CallPair(deposit, receipt);
В этом случае ваш CallPair
класс может вычислить и выставить условие равенства суммы следующим образом:
Convert.ToDouble(deposit.Total.Split(" ").Last()) == receipt.PaidIn;
Гораздо более понятным подходом было бы изменить класс, используемый для отображения ваших записей ERP:
public class DepositAssembly
{
public string VoucherNo { get; set; }
// In DDD the following props would be encapsulated into a "Money" value-object
public string Currency {get;set;} // The type of currency, eg.: GBP
public double Total { get; set; } // The amount of the deposit
}
Тогда вычисление суммы равенства будет проще:
deposit.Amount == receipt.PaidIn;
Поскольку это довольно тривиально, вы можете выбрать между добавлением этого в свой класс CallPair
или его вычислением при итерации объединенных значений (что необходимо сделать для проверки вашей второй цели).
По сути, это просто цикл внутри цикла, но с использованием linq-запроса «All», который сравнивает каждую DepositAssembly с каждой MpesaAssembly.
var result1 = DepositAssemblies.All(Deposit => MpesaAssemblies.Any(mpesa => mpesa.PaidIn.ToString() == Deposit.Total.ToString() &&
mpesa.ReceiptNo.ToString() == Deposit.VoucherNo.ToString()));
Думайте Правильный способ сделать это, хотя это создавать анонимные типы
var MatchesSolution1 = from Deposits in DepositAssemblies
join Mpesas in MpesaAssemblies on new { Amount = Mpesas.PaidIn.ToString(), No = Mpesas.ReceiptNo.ToString() }
equals new { Amount = Deposits.Total.ToString(), No = Deposits.VoucherNo.ToString() }
Другое решение использует пересечение (которое должно работать быстрее всего)
var MatchesSolution2= DepositAssemblies.Select(Deposit => new { Amount = Deposit.Total.ToString(), No = Deposit.VoucherNo.ToString() })
.Intersect(MpesaAssemblies.Select(Mpesa => new { Amount = Mpesa.PaidIn.ToString(), No = Mpesa.ReceiptNo.ToString() }))
.ToList();
Надеюсь, это поможет.
Похожие вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.