2013-05-27 6 views
3

Я хочу проверить, существует ли DataRow из одного DataTable в другом DataTable.C#: Проверка наличия datarow в другом datatable с динамическими столбцами

У меня есть две таблицы данных. Там будут некоторые DataRows, которые одинаковы и существуют в обоих. Это было бы так легко, если бы я знал, какие столбцы будут там каждый раз, но я этого не делаю. Используя что-то вдоль линий ...

datatable.Rows[i].Field <String> columnName); 

не будет работать, так как это поле может быть целое число, строка или дата/время. Однако я знаю, что два файла имеют одинаковые имена столбцов.

Мой код в кусках, но это то, на что оно похоже. Сейчас я создаю список имен столбцов, но об этом.

for (var h = 0; h < origDbfFile.datatable.Columns.Count; h++) { 

    columnNames.Add(origDbfFile.datatable.Columns[h].ColumnName); 

} 

У меня есть кошмар петли, если кто-то может найти более чистое решение, было бы очень признательно!

for (int g = 0; g < origDbfFile.dataset.Tables[0].Rows.Count; g++) 
{ 

    for (int h = 0; i < modDbfFile.dataset.Tables[0].Columns.Count; h++) 
    { 
      foreach (String columnName in columnNames) 
      { 
      String rowValue = origDbfFile.dataset.Tables[0].Rows[g].Field<String>(Convert.ToString(columnName)); 
      //test data 
      result += "Column name: &nbsp: " + columnName + "<br/>"; 
      result += "Value &nbsp; " + rowValue + "<br/><br/>"; 
      //if logic will go below 

      } 

     } 

} 
+0

Ваш вложенный цикл (h) объявляет 'h', но проверяет его на' i'. – Jay

ответ

2

Мое решение было захватить значение не как целое, строка или дата/время, ... но как родовой объект. Затем оттуда я могу преобразовать его в строку, а затем сравнить, как если бы это была строка.

//check each column name for a change 
foreach (String columnName in columnNames) 
{ 
    //this grabs whatever value is in that field        
    String origRowValue = "" + origRow.Field<Object>(columnName); 
    String modRowValue = "" + modRow.Field<Object>(columnName); 

    //check if they are the same 
    if (origRowValue.Equals(modRowValue)) 
    { 
     //if they aren the same, increase the number matched by one 
     numberMatched++; 
     //add the column to the list of columns that don't match 

    } 
    else 
    { 
     mismatchedColumns.Add(columnName); 
    } 

} 

Умное решение или что? Спасибо за всю помощь всем :)

0

Если вы используете .NET 3.5 или более поздней версии что-то вроде этого будет вам список имен столбцов, которые существуют в обеих таблицах.

var columns = origDbfFile.datatable.Columns 
    .Select(o => o.ColumnName) 
    .Intersect(modDbfFile.datatable.Columns 
       .Select(m => m.ColumnName)); 

Хотя я не уверен, что это решает вашу общую проблему. Не могли бы вы прояснить немного больше?

+0

Схватить имена столбцов не составит труда. Проблема заключается в том, что я выполняю свои проверки для каждого поля (скажем, например, id, emp_start_date и т. Д.). Я не могу динамически определить, какое это поле.(int, string, double, date и т. д.) Я сейчас рассматриваю этот класс как возможное решение. http://msdn.microsoft.com/en-us/library/system.data.datarowcomparer.aspx У меня нет кода передо мной прямо сейчас. –

2

Предполагая, что у вас нет проблем с бокс/unboxing и значениями/ссылочными типами значений строк, ваш код в значительной степени зависит от конкретной ситуации.

Конечно, вы можете сделать это фантазер с Linq и расширения методов, если вы в них

public static class DataRowExtensions 
{ 
    public static int IndexIn(this DataRow thisRow, DataTable table) 
    { 
     return table.Rows 
      .OfType<DataRow>() 
      .Select((row, i) => new { row, index = i + 1 }) 
      .Where(pair => EqCondition(thisRow, pair.row)) 
      .Select(pair => pair.index) 
      .FirstOrDefault() - 1; 
    } 

    public static bool EqCondition(DataRow row1, DataRow row2) 
    { 
     // check for the equality of row values 
     return true; 
    } 
} 

... 

for (int i = 0; i < tab1.Rows.Count; i++) 
{ 
    var index = tab1.Rows[i].IndexIn(tab2); 

    if (index < 0) 
    { 
     Console.WriteLine("The row at index {0} was not found in second table", i); 
    } 
    else 
    { 
     Console.WriteLine("The row at index {0} was found in second table at index", i, index); 
    } 
} 

но кроме нарушения после первого матча обнаружили, что код совсем то же самое.

Мое рекогносцирование состоит в том, чтобы использовать равенство идентификаторов, учитывая, что в большинстве случаев данные поступают из источников данных с индексами, и вы можете оказаться в этом случае.

PS. в вашем втором для у вас есть 2 ошибки

  • вы объявили час, но использовать I
  • Я полагаю, вы должны были использовать. Ряды .Count
+0

Спасибо, я дам этому завтрашний день и дам вам знать, как это происходит! –

Смежные вопросы