¿Cómo 'unir' 2 o más DataTables en C#?¿Cómo 'unir' 2 o más DataTables en C#?
Ambas tablas tienen la misma estructura.
¿Hay alguna función incorporada o deberíamos hacerlo manualmente?
¿Cómo 'unir' 2 o más DataTables en C#?¿Cómo 'unir' 2 o más DataTables en C#?
Ambas tablas tienen la misma estructura.
¿Hay alguna función incorporada o deberíamos hacerlo manualmente?
Usted está mirando más probable para el método DataTable.Merge.
Ejemplo:
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();
}
}
Usted podría intentar esto:
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;
}
De here (no probado).
Se puede usar de concatenación de LINQ a conjuntos de datos (obtener el capítulo libre de LINQ en Acción) para montarlas y luego .AsDataTable para crear la tabla (suponiendo que realmente los quieren como un DataTable)
no estoy utilizando LINQ ... – Dhana
LINQ es como el jQuery del universo de acceso a datos .NET, es la respuesta a todo. – TheTXI
@LazyBoy: lo tendrá pronto (aunque, en serio, el capítulo del libro pasa por el ensamblado System.Data.DataSetExtensions y por las afinidades que ofrece que extienden los DataSets para ofrecer incluso más potencia de la que los DataSets ya ofrecen (y con ese poder intrincado). ..)). @TheTXI: Si no se puede hacer rociando en algunos PS y algunos LINQ, ¿cuál es el punto: D –
encontré con este pregunta, y Ruben Bartelink dio una gran respuesta, pero sin código. Así que tuve que buscarlo en otro lado, lo que derrota el punto de StackOverflow. Ahora que es 2010, las otras respuestas dadas no son tan viables. Como referencia, aquí está el código que demuestra el método de extensión CopyToDataTable(). Es en VB con el fin de no robar el crédito de Ruben si quiere volver al pasado y publicar una respuesta más completa :)
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
Prueba esto utilizando LINQ to DataSet, debe agregar la referencia para System.Data. DataSetExtensions.dll, otro enfoque, alternativa para el método 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;
}
Antonio
mejor quiere también tener en cuenta el caso cuando ambas tablas de datos tienen un registro coincidente (mismos valores para todas las columnas) –