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

hat*_*man 12 c# datatable

首先,我需要从 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 
Run Code Online (Sandbox Code Playgroud)

数据库中的表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
Run Code Online (Sandbox Code Playgroud)

合并后的数据表如下所示:

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 
Run Code Online (Sandbox Code Playgroud)

但是合并的输出数据表应该是这样的(有可能进一步使用它):

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 
Run Code Online (Sandbox Code Playgroud)

在 中查找重复项NAME。只留下其中一个,从表 1 到NRO表 2 到分配一个数字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);

        }
Run Code Online (Sandbox Code Playgroud)

然后我从另一个表 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);
          }
Run Code Online (Sandbox Code Playgroud)

之后我正在执行过滤(我需要的行只以 4 和 1 in 开头NRO,还有其他起始编号的行):

DataTable results = dataTable.Select("ACTIVE = '1' AND (NRO Like '1%' OR NRO Like '4%')").CopyToDataTable();
Run Code Online (Sandbox Code Playgroud)

然后我再添加一个 Column NRO1(这也是添加零 (0) 我在 Column 中不需要它们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
        }
Run Code Online (Sandbox Code Playgroud)

我可以使用此代码捕获重复项

var duplicates = results.AsEnumerable().GroupBy(r => r[2]).Where(gr => gr.Count() > 1);
Run Code Online (Sandbox Code Playgroud)

但如何执行其余的?这应该通过构建新表的循环来执行吗?我如何执行加入和删除重复项dataTable

小智 3

您可以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;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)