Почему мой запрос Linq GroupBy не возвращает правильные значения count?

#c# #linq #csv #datatable

#c# #linq #csv #datatable

Вопрос:

Следующий код считывает CSV-файл в DataTable. Затем он перебирает все столбцы в таблице данных и пытается сгенерировать количество всех отдельных значений в каждом столбце с помощью запроса Linq:

 var g = allValues.AsEnumerable().GroupBy(i => i);
 

Почему значение «grp.Count ()» никогда не превышает 1, хотя я знаю, что все столбцы содержат повторяющиеся значения?

         private void button13_Click(object sender, System.EventArgs e)
    {
        DataSet ds = GetDataFromCSVFile(-1);

        DataTable table = ds.Tables[0];

        int test = 0;
        string[] columnToSearch = { "" };

        IList<ColumnDetail> colDetails = new List<ColumnDetail>();

        foreach (DataColumn col in table.Columns)
        {
            columnToSearch[0] = col.ToString();

            DataTable allValues = GetAllValuesFromColumn(table, columnToSearch);

            var g = allValues.AsEnumerable().GroupBy(i => i);

            test = 0;
            foreach (var grp in g)
            {
                if (grp.Count() > 1)
                    MessageBox.Show(" grp.Key.ItemArray[0].ToString() : "   grp.Key.ItemArray[0].ToString()   " Cnt: "   grp.Count());
                test  ;
            }
            MessageBox.Show("Count is: "   test);
        }
    }
 

Ответ №1:

Методы Equals и GetHashCode DataRow основаны не на значениях каждой строки, а на ссылке на объект. Две строки с одинаковыми значениями столбцов не равны. Вместо этого вам нужно будет создать пользовательский интерфейс IEqualityComparer для сравнения строк на основе значений каждого столбца.

В данном конкретном случае подходящая реализация уже написана в форме DataRowComparer класса, поэтому вы можете просто использовать DataRowComparer.Default как IEqualityComparer при группировании в группу на основе значения строк вместо ссылки на строки.

Комментарии:

1. Спасибо Servy. Это решило мою проблему. Я изменил строку: var g = allValues . AsEnumerable().GroupBy(i => i); для переменной g = allValues . AsEnumerable().GroupBy(i => i, DataRowComparer. По умолчанию);