Как объединить 2 или более DataTables в C #? - PullRequest
13 голосов
/ 28 мая 2009

Как объединить 2 или более DataTables в C #?

Обе таблицы имеют одинаковую структуру.

Есть ли встроенная функция или мы должны делать это вручную?

Ответы [ 5 ]

13 голосов
/ 28 мая 2009

Скорее всего, вы ищете метод DataTable.Merge .

Пример

private static void DemonstrateMergeTable()
{
    DataTable table1 = new DataTable("Items");

    // Add columns
    DataColumn idColumn = new DataColumn("id", typeof(System.Int32));
    DataColumn itemColumn = new DataColumn("item", typeof(System.Int32));
    table1.Columns.Add(idColumn);
    table1.Columns.Add(itemColumn);

    // Set the primary key column.
    table1.PrimaryKey = new DataColumn[] { idColumn };

    // Add RowChanged event handler for the table.
    table1.RowChanged += new 
        System.Data.DataRowChangeEventHandler(Row_Changed);

    // Add ten rows.
    DataRow row;
    for (int i = 0; i <= 9; i++)
    {
        row = table1.NewRow();
        row["id"] = i;
        row["item"] = i;
        table1.Rows.Add(row);
    }

    // Accept changes.
    table1.AcceptChanges();
    PrintValues(table1, "Original values");

    // Create a second DataTable identical to the first.
    DataTable table2 = table1.Clone();

    // Add column to the second column, so that the 
    // schemas no longer match.
    table2.Columns.Add("newColumn", typeof(System.String));

    // Add three rows. Note that the id column can't be the 
    // same as existing rows in the original table.
    row = table2.NewRow();
    row["id"] = 14;
    row["item"] = 774;
    row["newColumn"] = "new column 1";
    table2.Rows.Add(row);

    row = table2.NewRow();
    row["id"] = 12;
    row["item"] = 555;
    row["newColumn"] = "new column 2";
    table2.Rows.Add(row);

    row = table2.NewRow();
    row["id"] = 13;
    row["item"] = 665;
    row["newColumn"] = "new column 3";
    table2.Rows.Add(row);

    // Merge table2 into the table1.
    Console.WriteLine("Merging");
    table1.Merge(table2, false, MissingSchemaAction.Add);
    PrintValues(table1, "Merged With table1, schema added");

}

private static void Row_Changed(object sender, 
    DataRowChangeEventArgs e)
{
    Console.WriteLine("Row changed {0}\t{1}", e.Action, 
        e.Row.ItemArray[0]);
}

private static void PrintValues(DataTable table, string label)
{
    // Display the values in the supplied DataTable:
    Console.WriteLine(label);
    foreach (DataRow row in table.Rows)
    {
        foreach (DataColumn col in table.Columns)
        {
            Console.Write("\t " + row[col].ToString());
        }
        Console.WriteLine();
    }
}
4 голосов
/ 28 мая 2009

Вы можете попробовать это:

public static DataTable Union (DataTable First, DataTable Second)
{

      //Result table
      DataTable table = new DataTable("Union");

      //Build new columns
      DataColumn[] newcolumns = new DataColumn[First.Columns.Count];

      for(int i=0; i < First.Columns.Count; i++)
      {
          newcolumns[i] = new DataColumn(
          First.Columns[i].ColumnName, First.Columns[i].DataType);
      }

      table.Columns.AddRange(newcolumns);
      table.BeginLoadData();

      foreach(DataRow row in First.Rows)
      {
           table.LoadDataRow(row.ItemArray,true);
      }

      foreach(DataRow row in Second.Rows)
      {
          table.LoadDataRow(row.ItemArray,true);
      }

      table.EndLoadData();
      return table;
}

С здесь (не тестировалось).

2 голосов
/ 28 мая 2009

Вы можете использовать Concat из Linq для наборов данных (получите бесплатную главу LINQ in Action), чтобы присоединиться к ним, а затем .AsDataTable, чтобы создать таблицу (при условии, что вы действительно хотите, чтобы они были в виде DataTable)

1 голос
/ 16 июля 2010

Наткнулся на этот вопрос, и Рубен Бартелинк дал отличный ответ, но без кода. Поэтому мне пришлось искать это в другом месте, что побеждает точку StackOverflow. Теперь, когда наступил 2010 год, другие ответы не столь жизнеспособны. Для справки вот код, демонстрирующий метод расширения CopyToDataTable (). Это в VB, чтобы не украсть кредит у Рубена, если он хочет вернуться к прошлому и опубликовать более полный ответ:)

Public Function GetSchema(ByVal dbNames As IEnumerable(Of String)) As DataTable
   Dim schemaTables As New List(Of DataTable)()
   For Each dbName As String In dbNames
      Dim cnnStr = GetConnectionString(dbName)
      Dim cnn As New SqlConnection(cnnStr)
      cnn.Open()
      Dim dt = cnn.GetSchema("Columns")
      cnn.Close()
      schemaTables.Add(dt)
   Next

   Dim dtResult As DataTable = Nothing
   For Each dt As DataTable In schemaTables
      If dtResult Is Nothing Then
         dtResult = dt
      Else
         dt.AsEnumerable().CopyToDataTable(dtResult, LoadOption.PreserveChanges)
      End If
   Next

   Return dtResult
End Function
0 голосов
/ 18 июня 2012

Попробуйте это с помощью Linq to DataSet, необходимо добавить ссылку на System.Data.DataSetExtensions.dll, другой подход, альтернативный для метода DataTable.Merge)

static void Main(string[] args)
{
    DoUnion();
}

private static void DoUnion()
{
    DataTable table1 = GetProducts();
    DataTable table2 = NewProducts();
    var tbUnion = table1.AsEnumerable()
        .Union(table2.AsEnumerable());
    DataTable unionTable = table1.Clone();
    foreach (DataRow fruit in tbUnion)
    {
        var fruitValue = fruit.Field<string>(0);
        Console.WriteLine("{0}->{1}", fruit.Table, fruitValue);
        DataRow row = unionTable.NewRow();
        row.SetField<string>(0, fruitValue);
        unionTable.Rows.Add(row);
    }
}

private static DataTable NewProducts()
{
    DataTable table = new DataTable("CitricusTable");
    DataColumn col = new DataColumn("product", typeof(string));
    table.Columns.Add(col);
    string[] citricusFruits = { "Orange", "Grapefruit", "Lemon", "Lime", "Tangerine" };
    foreach (string fruit in citricusFruits)
    {
        DataRow row = table.NewRow();
        row.SetField<string>(col, fruit);
        table.Rows.Add(row);
    }
    return table;
}

private static DataTable GetProducts()
{
    DataTable table = new DataTable("MultipleFruitsTable");
    DataColumn col = new DataColumn("product", typeof(string));
    table.Columns.Add(col);
    string[] multipleFruits = { "Breadfruit", "Custardfruit", "Jackfruit", "Osage-orange", "Pineapple" };
    foreach (string fruit in multipleFruits)
    {
        DataRow row = table.NewRow();
        row.SetField<string>(col, fruit);
        table.Rows.Add(row);
    }
    return table;
}

антонио

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...