Я пытаюсь создать запрос LINQ для List<KeyValuePair<string, string>>
, который сообщает мне, сколько (если есть) дубликатов KeyValue в списке. Для этого я попытался создать Dictionary<KeyValuePair<string, string>, int>
, где ключом словаря является KeyValuePair из списка, а значением словаря является число раз, которое пара встречается в исходном списке. Мой код компилируется, но в настоящее время он говорит мне, что каждая из KeyValuePairs в списке дублируется.
Чтобы обеспечить некоторый контекст, этот метод вызывается в веб-форме .NET / DNN для проверки файла, загруженного одним из наших клиентов; форма МОЖЕТ иметь дубликаты номеров счетов, но может не иметь дубликатов счетов и номеров деталей; следовательно, List<KeyValuePair<string, string>>
представляет собой сочетание номеров счетов и номеров деталей. Значение int в словаре должно указывать количество раз, когда каждая пара номеров счетов-фактур появляется в главном списке. Данные извлекаются из элемента управления GridView, который содержит данные из файла загрузки.
За последние пару часов я проработал кучу статей LINQ, чтобы попытаться повторить код для создания словаря с таким списком, но мне это не удалось. Эта статья предоставила много полезной информации:
C # LINQ найти дубликаты в списке
Также обратите внимание, что этот код реализован в DNN, что делает его ОЧЕНЬ трудным для отладки. Я не могу пошагово пройти через мой код, чтобы определить проблему, поэтому, пожалуйста, наберитесь терпения.
private void CheckBranchNumbersFile(GridView Upload)
{
List<KeyValuePair<string, string>> invoiceAndPart = new List<KeyValuePair<string, string>>();
for (int i = 0; i < Upload.Rows.Count; ++i)
{
KeyValuePair<string, string> pair = new KeyValuePair<string, string>(Upload.Rows[i].Cells[2].ToString(), Upload.Rows[i].Cells[5].ToString());
invoiceAndPart.Add(pair);
}
List<KeyValuePair<string, string>> invoiceAndPartUnsorted = new List<KeyValuePair<string, string>>(invoiceAndPart);
var query = invoiceAndPart.GroupBy(x => x).Where(g => g.Count() > 1).ToDictionary(x => x.Key, y => y.Count());
foreach (KeyValuePair<KeyValuePair<string, string>, int> invPartCount in query)
{
int count = invPartCount.Value;
if (count > 1)
{
IsNotValid = true;
for (int i = 0; i < invoiceAndPartUnsorted.Count; ++i)
{
if (invoiceAndPartUnsorted[i].Key.Equals(invPartCount.Key.Key) && invoiceAndPartUnsorted[i].Value.Equals(invPartCount.Key.Value))
{
// This block highlights the cells on the review screen for the client to see erroneous data
Upload.Rows[i].Cells[2].BackColor = Color.Red;
Upload.Rows[i].Cells[5].BackColor = Color.Red;
Upload.Rows[i].Cells[2].ToolTip = "Cannot have duplicate invoice AND part numbers";
Upload.Rows[i].Cells[5].ToolTip = "Cannot have duplicate invoice AND part numbers";
}
}
}
}
}
См. Следующий воспроизводимый пример:
// Populate list with sample invoice/part numbers, including some duplicates
List<KeyValuePair<string, string>> data = new List<string, string>();
KeyValuePair<string, string> sample1 = new KeyValuePair<string, string>("ABC", "100");
KeyValuePair<string, string> sample2 = new KeyValuePair<string, string>("FFF", "250");
KeyValuePair<string, string> sample3 = new KeyValuePair<string, string>("XYZ", "100");
KeyValuePair<string, string> sample4 = new KeyValuePair<string, string>("ABC", "100");
KeyValuePair<string, string> sample5 = new KeyValuePair<string, string>("ABC", "100");
data.Add(sample1);
data.Add(sample2);
data.Add(sample3);
data.Add(sample4);
data.Add(sample5);
// Create copy of data before data is grouped by LINQ query
List<KeyValuePair<string, string>> data2 = new List<string, string>(data);
// Perform LINQ Query to create Dictionary<KeyValuePair<string, string>, int> that reports number of occurences of each KeyValuePair<string, string> in @variable ata
var query = data.GroupBy(x => x).Where(g => g.Count() > 1).ToDictionary(x => x.Key, y => y.Count());
// Using foreach loop, identify the indices in @variable data2 that contain duplicated entries
foreach (KeyValuePair<KeyValuePair<string, string>, int> pair in query)
{
int count = pair.Value;
// This pair represents a duplicate because its value > 1
if (count > 1)
{
// Find the entry in data2 that matches this pair
for (int i = 0; i < data2.Count; ++i)
{
if (data2[i].Equals(pair.Key))
{
Console.WriteLine("Match in list data2 found at index: " + i);
}
}
}
}
// The console should write:
// Match in list data2 found at index: 0
// Match in list data2 found at index: 3
// Match in list data3 found at index: 4
// Thank you! :)
Я ожидаю, что экран обзора будет отмечать только ячейки для строк с дублирующимися номерами счетов-фактур и деталей как ошибки, но он помечает эти ячейки для каждой строки данных в файле. Например, если во входном файле Excel имеется 10 строк, и 3 из них содержат повторяющиеся счета-фактуры И номера деталей, то эти ячейки должны быть окрашены в красный цвет и отмечены подсказкой, а НЕ всеми 10 строками. Ячейки 2 и 5 каждой строки содержат номер счета и номер детали соответственно. Вот скриншот того, что он делает сейчас: https://gyazo.com/a2c8203627fe81f763c48008d0ba9e33
В этом примере только последние 3 строки должны иметь ячейки 2 и 5, выделенные красным; другие ячейки, выделенные в предыдущих строках, в порядке (другие валидаторы для пустых полей).
РЕДАКТИРОВАТЬ: Включен воспроизводимый пример. Это мой первый пост здесь, так что, пожалуйста, критикуйте мой этикет! Спасибо!