2012-05-29 8 views
3

Я новичок в программировании, так что это может показаться несколько простеньким, но я не могу понять это.Найти повторяющиеся записи C#

Я пытаюсь найти повторяющиеся значения, которые находятся в datatable в одном столбце значений.

Вот что я пытался это сделать.

DataRow[] dupresults = dt.Select("PROV_NEW"); 
TableIssues = string.Empty; 
DataTable dtTemp = dt.DefaultView.ToTable(true, "NEW_PROV"); 

if (dupresults.Length == 0) 
{ 
    return true; 
} 
else 
{ 
    foreach (DataRow item in dupresults) 
    { 
     Console.WriteLine(item[1]); 
     TableIssues += "Provider Code is not unique for " + item[1].ToString() + ". Revise non-unique codes.\r\n\n\n\n"; 
    } 
    return false; 
} 

Хорошо, но я также иметь его поиск, чтобы убедиться, что там нет пустых полей в PROV_NEW тоже. поэтому я не знаю, где это сделать. Я очень новичок в C#. Я только начал на прошлой неделе. Я делаю побочные проекты для компании моего отца.

private bool ValidateTable(DataSets.Setup.SETUP_MWPROVDataTable dt, out string TableIssues) 
    { 
     try 
     { 
      //NewCode not used for other row 
      DataRow[] result = dt.Select("PROV_NEW = ''"); 
      DataRow[] dupresults = dt.Select("PROV_NEW"); 
      TableIssues = string.Empty; 
      DataTable dtTemp = dt.DefaultView.ToTable(true, "NEW_PROV"); 



      if (dupresults.Length == 0) 
      { 

       return true; 
      } 
      else 
      { 
       var duplicates = dt.AsEnumerable() 
       .Select(dr => dr.Field<string>("PROV_NEW")) 
       .GroupBy(x => x) 
       .Where(g => g.Count() > 1) 
       .Select(g => g.Key) 
       .ToList(); 

       foreach (DataRow item in dupresults) 
       { 
        Console.WriteLine(item[1]); 
        TableIssues += "Provider Code is not unique for " + item[1].ToString() + ". Revise non-unique codes.\r\n\n\n\n"; 
       } 
       return false; 
      } 


      if (result.Length == 0) 
      { 
       //TODO: Add Next Step for validation 

       return true; 

      } 
      else 
      { 
       foreach (DataRow item in result) 
       { 
        Console.WriteLine(item[1]); 
        TableIssues += "Provider code " + item[1].ToString() + " is blank. Add new Provider code for " + item[1].ToString() +".\r\n\n\n"; 
       } 


       return false; 
      } 

      } 
     catch (Exception) 
     { 

      throw; 
     } 
    } 


} 
+2

Пожалуйста, не конкатенации строк в цикле. Используйте 'StringBuilder'. Возможно, это не важно для этого первого проекта, но это хорошая привычка. –

+0

Что не работает? Вы получаете сообщение об ошибке? – FishBasketGordo

+0

Я продолжаю получать сообщение об ошибке: «Выражение фильтра« PROV_NEW »не оценивается с помощью булевого термина». Поэтому я не знаю, что там происходит – Kobrien

ответ

13

LINQ может помочь вам здесь:

var duplicates = dt.AsEnumerable() 
        .Select(dr => dr.Field<string>("PROV_NEW")) 
        .GroupBy(x => x) 
        .Where(g => g.Count() > 1) 
        .Select(g => g.Key) 
        .ToList(); 

// Now work with the set of duplicates 

В качестве альтернативы:

HashSet<string> providers = new HashSet<string>(); 
foreach (var provider in dt.AsEnumerable() 
          .Select(dr => dr.Field<string>("PROV_NEW"))) 
{ 
    if (!providers.Add(provider)) 
    { 
     // This provider is a duplicate 
    } 
} 

(Это работает, потому что HashSet<T>.Add возвращает ложь, если значение уже существует в наборе.)

+0

Как всегда, мастер LINQ. –

+0

Какова была бы реализация HashSet, если бы у меня был составной ключ для сравнения? В этом примере показан только один ключ «PROV_NEW» –

+0

@ LetsKickSomeAssin.net: Возможно, я использовал анонимный тип - анонимные типы уже реализуют равенство соответствующим образом, используя сравнение равенства по умолчанию для каждого компонента. –

0

dtEmp - ваш рабочий документ

DataTable distinctTable = dtEmp.DefaultView.ToTable(/*distinct*/ true); 
1

Jon Skeet's Принимая советы по использованию анонимного типа LINQ на несколько колонок ВЫБОРА, я получил себе решение, надеюсь, это поможет вам тоже:

DataTable dt_ = _data.Tables["MyTable"]; 

     foreach (DataRow _dr in dt_.AsEnumerable() 
     .GroupBy(r => new 
     { 
      c1 = r.Field<string>("ColNAME1 of table dt_"), 
      c2 = r.Field<string>("ColNAME2 of table dt_"), 
      c3 = r.Field<string>("ColNAME3 of table dt_"), 
    ...<any number of columns can be added> 
     }).Where(grp => grp.Count() > 1).SelectMany(itm => itm)) 
     { 
     // Handle your Duplicate row entry 
     }