【发布时间】:2016-07-27 20:14:24
【问题描述】:
我正在编写一个连接不同数据库系统的 C# 应用程序。这些系统可以是平面文件 db、Oracle、Sql、Excel 文件等。 C# 应用程序的工作是为在一个地方提供所有这些源代码提供一个出口。所以基本上,该应用程序接受相应数据库系统的查询和连接设置列表并收集一堆结果。
目标是输出一个单一的数据表,其中所有这些查询的结果都连接/联合在一起(取决于设置)。 C# 是否提供了一种简单的方法来对数据表列表执行任何联接/联合操作?
例如:
Table1:
__________________________________________________________
|tb1_pk_id| tb1_name | tb1_data1 | tb1_data2 |
|---------|---------------|---------------|---------------|
| 1 | tb1name_blah1 | tb1dat1_blah1 | tb1dat2blah1 |
| 2 | tb1name_blah2 | tb1dat1_blah2 | tb1dat2blah2 |
| 3 | tb1name_blah3 | tb1dat1_blah3 | tb1dat2blah3 |
-----------------------------------------------------------
Table2:
__________________________________________________________
|tb2_pk_id| tb2_name | tb2_data1 | tb2_data2 |
|---------|---------------|---------------|---------------|
| 1 | tb2name_blah1 | tb2dat1_blah1 | tb2dat2blah1 |
| 2 | tb2name_blah2 | tb2dat1_blah2 | tb2dat2blah2 |
| 3 | tb2name_blah3 | tb2dat1_blah3 | tb2dat2blah3 |
-----------------------------------------------------------
Join Results:
__________________________________________________________ _______________________________________________
|tb1_pk_id| tb1_name | tb1_data1 | tb1_data2 | tb2_name | tb2_data1 | tb2_data2 |
|---------|---------------|---------------|---------------|---------------|---------------|---------------|
| 1 | tb1name_blah1 | tb1dat1_blah1 | tb1dat2blah1 | tb2name_blah1 | tb2dat1_blah1 | tb2dat2blah1 |
| 2 | tb1name_blah2 | tb1dat1_blah2 | tb1dat2blah2 | tb2name_blah2 | tb2dat1_blah2 | tb2dat2blah2 |
| 3 | tb1name_blah3 | tb1dat1_blah3 | tb1dat2blah3 | tb2name_blah3 | tb2dat1_blah3 | tb2dat2blah3 |
-----------------------------------------------------------------------------------------------------------
到目前为止,我在网上找到了以下代码 (here) 来对所有数据进行合并:
private DataTable MergeAll(IList<DataTable> tables, String primaryKeyColumn)
{
if (!tables.Any())
throw new ArgumentException("Tables must not be empty", "tables");
if (primaryKeyColumn != null)
foreach (DataTable t in tables)
if (!t.Columns.Contains(primaryKeyColumn))
throw new ArgumentException("All tables must have the specified primarykey column " + primaryKeyColumn, "primaryKeyColumn");
if (tables.Count == 1)
return tables[0];
DataTable table = new DataTable("TblUnion");
table.BeginLoadData(); // Turns off notifications, index maintenance, and constraints while loading data
foreach (DataTable t in tables)
{
table.Merge(t); // same as table.Merge(t, false, MissingSchemaAction.Add);
}
table.EndLoadData();
if (primaryKeyColumn != null)
{
// since we might have no real primary keys defined, the rows now might have repeating fields
// so now we're going to "join" these rows ...
var pkGroups = table.AsEnumerable()
.GroupBy(r => r[primaryKeyColumn]);
var dupGroups = pkGroups.Where(g => g.Count() > 1);
foreach (var grpDup in dupGroups)
{
// use first row and modify it
DataRow firstRow = grpDup.First();
foreach (DataColumn c in table.Columns)
{
if (firstRow.IsNull(c))
{
DataRow firstNotNullRow = grpDup.Skip(1).FirstOrDefault(r => !r.IsNull(c));
if (firstNotNullRow != null)
firstRow[c] = firstNotNullRow[c];
}
}
// remove all but first row
var rowsToRemove = grpDup.Skip(1);
foreach (DataRow rowToRemove in rowsToRemove)
table.Rows.Remove(rowToRemove);
}
}
return table;
}
这很适合做一个联合,但我不知道 .NET 中是否已经存在一种更简单的方法可以让我做 ANY 种类在一组单独的 DataTables 上加入或联合(不仅仅是上面代码中的联合)还是我必须自定义编码每种类型的加入/联合?
【问题讨论】: