[英]Build one datatable out of two with certain conditions
首先,我需要从 ODBC 获取所有数据(这已经在工作了)。
然后是最复杂的部分,我还不确定如何完成。 ODBC 中有两个数据表。 我正在将它们与我当前的代码合并并使用某些参数过滤它们。
数据库中的表1:
NRO NAME NAMEA NAMEB ADDRESS POSTA POSTN POSTADR COMPANYN COUNTRY ID ACTIVE
123 Fiat Punto 500 J5 K4 O3 P4 O2 JT 1 1
133 Opel Meriva FTG J5 K4 O3 P4 O2 JO 3 1
153 MB E200 C25 JN KI OP PY OR JD 5 1
183 BMW E64 SE0 JR KE OT PG OL J8 9 1
103 Audi S6 700 JP KU OU PN OH J6 11 1
数据库中的表2:
NRO NAME NAMEA NAMEB ADDRESS POSTA POSTN POSTADR COMPANYN COUNTRY ID ACTIVE
423 Fiat Punto 500 J5 K4 O3 P4 O2 JT 1 1
463 BMW E64 SE0 JR KE OT PG OL J8 9 1
合并后的数据表如下所示:
NRO NAME NAMEA NAMEB ADDRESS POSTA POSTN POSTADR COMPANYN COUNTRY ID ACTIVE
423 Fiat Punto 500 J5 K4 O3 P4 O2 JT 1 1
463 BMW E64 SE0 JR KE OT PG OL J8 9 1
123 Fiat Punto 500 J5 K4 O3 P4 O2 JT 1 1
133 Opel Meriva FTG J5 K4 O3 P4 O2 JO 3 1
153 MB E200 C25 JN KI OP PY OR JD 5 1
183 BMW E64 SE0 JR KE OT PG OL J8 9 1
103 Audi S6 700 JP KU OU PN OH J6 11 1
但是合并的输出数据表应该是这样的(有可能进一步使用它):
NRO NRO1 NAME NAMEA NAMEB ADDRESS POSTA POSTN POSTADR COMPANYN COUNTRY ID ACTIVE
123 423 Fiat Punto 500 J5 K4 O3 P4 O2 JT 1 1
133 Opel Meriva FTG J5 K4 O3 P4 O2 JO 3 1
153 MB E200 C25 JN KI OP PY OR JD 5 1
183 463 BMW E64 SE0 JR KE OT PG OL J8 9 1
103 Audi S6 700 JP KU OU PN OH J6 11 1
在NAME
查找重复项。 只留下其中一个,将表 1 中的数字分配给表 2 中的NRO
到NRO1
。 表 1 编号应在NRO
,表 2 编号应在NRO1
。
连接到 ODBC 后,我正在用表 1 中的数据填充一张表
DataTable dataTable = new DataTable("COMPANY");
using (OdbcConnection dbConnectionSE = new OdbcConnection(connectionStringSE))
{
dbConnectionSE.Open();
OdbcDataAdapter dadapterSE = new OdbcDataAdapter();
dadapterSE.SelectCommand = new OdbcCommand(queryStringSE, dbConnectionSE);
dadapterSE.Fill(dataTable);
}
然后我从另一个表 2 中获取数据并通过以下方式合并它们:
using (OdbcConnection dbConnectionFI = new OdbcConnection(connectionStringFI))
{
dbConnectionFI.Open();
OdbcDataAdapter dadapterFI = new OdbcDataAdapter();
dadapterFI.SelectCommand = new OdbcCommand(queryStringFI, dbConnectionFI);
var newTable = new DataTable("COMPANY");
dadapterFI.Fill(newTable);
dataTable.Merge(newTable);
}
之后,我正在执行过滤(我需要在NRO
只有以 4 和 1 开头的行,还有其他起始编号的行):
DataTable results = dataTable.Select("ACTIVE = '1' AND (NRO Like '1%' OR NRO Like '4%')").CopyToDataTable();
然后我再为NRO1
添加一个列(这也是添加零 (0) 我在列NRO1
不需要它们):
results.Columns.Add("NRO1", typeof(int)).SetOrdinal(1);
foreach (DataRow row in results.Rows)
{
//need to set value to NewColumn column
row["NRO1"] = 0; // or set it to some other value
}
我可以使用此代码捕获重复项
var duplicates = results.AsEnumerable().GroupBy(r => r[2]).Where(gr => gr.Count() > 1);
但是如何执行其余的操作? 这应该通过构建新表的循环来执行吗? 如何对dataTable
执行加入和删除重复项?
您可以使用自定义方法替换merge()
调用,该方法同时进行合并和过滤。 请参阅下面的示例。 我认为这是比先合并(在结果表中引入重复行)然后过滤(即删除重复行)更好的方法。
这里,假设参数都具有相同的格式。 tTemp
表用作表t2
内容的临时存储,但具有额外的列。 这允许导入结果表中的行。
也许有一个更优雅的解决方案,但这应该按预期工作。 请注意,我忽略了您关于NRO
允许值的额外要求,我相信您可以轻松添加。
static void merge_it(DataTable t1, DataTable t2, DataTable tResult, DataTable tTemp)
{
tResult.Merge(t1);
tResult.Columns.Add("NRO1", typeof(int));
tTemp.Merge(t2);
tTemp.Columns.Add("NRO1", typeof(int));
foreach (DataRow row in tTemp.Rows)
{
string name1 = row.Field<string>("NAME");
string name2 = row.Field<string>("NAMEA");
DataRow[] matches = tResult.Select($"NAME = '{name1}' AND NAMEA = '{name2}'");
if (matches.Length > 0)
{
matches[0].SetField<int>("NRO1", row.Field<int>("NRO"));
}
else
{
tResult.ImportRow(row);
}
}
foreach (DataRow row in tResult.Rows)
{
if (row["NRO1"] == DBNull.Value)
{
row["NRO1"] = 0;
}
}
}
尝试这个:
为 Table1 设置 NRO1 的默认值 0(修改 queryStringSE)
例如:SELECT NRO,0 AS NRO1, NAME,NAMEA,NAMEB, ... FROM TABLE1
为 Table2 设置 NRO 的默认值 0(修改 queryStringFI)
例如:SELECT 0 AS NRO,NRO AS NRO1,NAME,NAMEA,NAMEB,...... FROM TABLE2
表 1 将如下所示:
NRO NRO1 NAME NAMEA NAMEB ADDRESS POSTA POSTN POSTADR COMPANYN COUNTRY ID ACTIVE
123 0 Fiat Punto 500 J5 K4 O3 P4 O2 JT 1 1
133 0 Opel Meriva FTG J5 K4 O3 P4 O2 JO 3 1
表 2 将如下所示:
NRO NRO1 NAME NAMEA NAMEB ADDRESS POSTA POSTN POSTADR COMPANYN COUNTRY ID ACTIVE
0 423 Fiat Punto 500 J5 K4 O3 P4 O2 JT 1 1
0 463 BMW E64 SE0 JR KE OT PG OL J8 9 1
添加以下代码行:
var carGroups = dataTable.AsEnumerable().GroupBy(row => new
{
Name = row.Field<string>("Name"),
NameA = row.Field<string>("NAMEA"),
NameB = row.Field<string>("NAMEB")
//Other fields.....
});
DataTable result = dataTable.Clone();
foreach(var grp in carGroups)
result.Rows.Add(grp.Sum(r1 => r1.Field<int>("NRO")), grp.Sum(r2 => r2.Field<int>("NRO1")), grp.Key.Name, grp.Key.NameA, grp.Key.NameB);
如果它们表示相同类型的实体,则可以在两个表中保留相同的列名,然后查看此代码
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();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.