C# 在特定条件下,从两个数据表中构建一个数据表

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

首先,我需要从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 
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;
}
}
}
试试这个:

  • 在表1和表2的查询中都包括NRO1字段
  • 为表1设置NRO1的默认值0(修改queryStringSE)

    e、 g:选择NRO,0作为NRO1,名称,名称A,名称B。。。来自表1

  • 为表2设置NRO的默认值0(修改queryStringFI)

    e、 g:选择0作为NRO,选择NRO作为NRO1,名称,名称A,名称B,。。。。。。来自表2

  • 表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
    
    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”接受第一个参数