C# 在特定条件下,从两个数据表中构建一个数据表
首先,我需要从ODBC获取所有数据(这已经在工作了) 然后是最复杂的部分,我还不知道如何才能做到。 ODBC中有两个数据表。我正在将它们与当前代码合并,并使用某些参数对它们进行过滤 数据库中的表1:C# 在特定条件下,从两个数据表中构建一个数据表,c#,datatable,C#,Datatable,首先,我需要从ODBC获取所有数据(这已经在工作了) 然后是最复杂的部分,我还不知道如何才能做到。 ODBC中有两个数据表。我正在将它们与当前代码合并,并使用某些参数对它们进行过滤 数据库中的表1: NRO NAME NAMEA NAMEB ADDRESS POSTA POSTN POSTADR COMPANYN COUNTRY ID ACTIVE 123 Fiat Punto 500 J5 K4 O3
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
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
数据库中的表2:
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
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
但是,合并的输出数据表应如下所示(以便能够进一步使用它):
在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开头的行,还有其他起始编号的行):
然后,我为NRO1
添加了一列(这也添加了零(0),我在NRO1
列中不需要它们):
我可以用这段代码捕获重复项
var duplicates = results.AsEnumerable().GroupBy(r => r[2]).Where(gr => gr.Count() > 1);
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();
}
}
但剩下的怎么做呢?这应该通过构建新表的循环来执行?如何将重复项加入和删除到
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;
}
}
}
static void merge_it(DataTable t1、DataTable t2、DataTable tResult、DataTable tTemp)
{
结果合并(t1);
tResult.Columns.Add(“NRO1”,typeof(int));
t合并(t2);
添加(“NRO1”,类型(int));
foreach(tTemp.Rows中的数据行)
{
字符串名称1=行字段(“名称”);
字符串name2=行字段(“NAMEA”);
DataRow[]matches=tResult.Select($“NAME='{name1}'和NAMEA='{name2}');
如果(匹配。长度>0)
{
匹配[0]。设置字段(“NRO1”,行。字段(“NRO”);
}
其他的
{
tResult.ImportRow(世界其他地区);
}
}
foreach(tResult.Rows中的数据行)
{
if(行[“NRO1”]==DBNull.Value)
{
行[“NRO1”]=0;
}
}
}
试试这个:
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
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
表2如下所示:
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
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);
var carGroups=dataTable.AsEnumerable().GroupBy(行=>new
{
名称=行字段(“名称”),
NameA=行字段(“NameA”),
NameB=行字段(“NameB”)
//其他领域。。。。。
});
DataTable结果=DataTable.Clone();
foreach(carGroups中的var grp)
result.Rows.Add(grp.Sum(r1=>r1.Field(“NRO”)),grp.Sum(r2=>r2.Field(“NRO1”)),grp.Key.Name,grp.Key.NameA,grp.Key.NameB);
如果两个表表示相同类型的实体,则可以在这两个表中保持相同的列名 然后看看这个代码
var duplicates = results.AsEnumerable().GroupBy(r => r[2]).Where(gr => gr.Count() > 1);
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();
}
}
private static void expressuremable()
{
DataTable table1=新的DataTable(“项目”);
//添加列
DataColumn idColumn=新的DataColumn(“id”,typeof(System.Int32));
DataColumn itemColumn=新的DataColumn(“项”,typeof(System.Int32));
表1.Columns.Add(idColumn);
表1.Columns.Add(itemColumn);
//设置主键列。
table1.PrimaryKey=新数据列[]{idColumn};
//为表添加RowChanged事件处理程序。
表1.1行更改+=新
System.Data.DataRowChangeEventHandler(行\u已更改);
//加十行。
数据行;
对于(int i=0;i 1.对于某些名称,dataTable
是否可以包含两个以上的重复项?例如,BMW是否可能存在三个重复项?2.我们如何定义要保留哪些重复项记录,以及要删除哪些重复项记录?例如,我们可以以最小的NRO
保留记录,并删除另一个记录。@iliartushev 1.数据表在NAME
中不能包含超过一个或两个“重复项”。如果超过两个-错误(错误处理程序).2.我的示例中有一个错误,我现在已经修复了。感谢您提到这一个,它很重要。您能分享queryStringFI和/或queryStringSE的值吗?加上您正在使用的数据库吗?@ATTA我无法提供对实际数据库的访问。您是指数据库类型吗?正如它在疑问中所读的那样-ODBC实际上,我喜欢查看查询中的数据然而,基于一些假设,我已经写下了答案。请回顾并给出您的反馈。感谢您!我想我做错了什么,因为我收到的“DataTable”不包含“Merge\u it”的定义,并且没有可访问的扩展方法“Merge\u it”接受第一个参数