【问题标题】:How to perform a Union All on 2 DataTables如何在 2 个 DataTables 上执行 Union All
【发布时间】:2015-12-31 08:55:35
【问题描述】:

我没有使用实体框架。 有2个数据表,每个都有不同的编号。的列。有一个共同的列 - ItemId

如果是 Union,我会使用“Merge”,但不知道如何为这 2 个 DataTables 执行 Union All

public static void Main()
    {
        //First DataTable
        DataTable dt1 = new DataTable();
        dt1.Columns.Add("ItemId");
        dt1.Columns.Add("Name");
        dt1.Columns.Add("Color");

        DataRow dr = dt1.NewRow();
        dr["ItemId"] = "1";
        dr["Name"] = "Name1";
        dr["Color"] = "Color1";
        dt1.Rows.Add(dr);

        dr = dt1.NewRow();
        dr["ItemId"] = "2";
        dr["Name"] = "Name2";
        dr["Color"] = "Color2";
        dt1.Rows.Add(dr);

        //Second DataTable
        DataTable dt2 = new DataTable();
        dt2.Columns.Add("ItemId");
        dt2.Columns.Add("Name");
        dt2.Columns.Add("Price");

        DataRow dr2 = dt2.NewRow();
        dr2["ItemId"] = "1";
        dr2["Name"] = "Name1";
        dr2["Price"] = "100";
        dt2.Rows.Add(dr2);

        dr2 = dt2.NewRow();
        dr2["ItemId"] = "2";
        dr2["Name"] = "Name3";
        dr2["Price"] = "200";
        dt2.Rows.Add(dr2);
    }

预期输出

ItemId  Name    Color   Price
1       Name1   Color1
2       Name2   Color2
1       Name1            100  
2       Name3            200

【问题讨论】:

  • 我不知道如何解释“有一个公用列 - ItemId”,因为似乎有两列名称相同(ItemIdName)并且它们似乎正在被处理与您的预期输出相同。
  • 我有点担心你想要的结果,因为它有重复的 ItemId。这种行为是否正确?
  • @KunalKakkad。是的,这种行为是正确的。 2 个数据表中的 ItemIds 可能相同
  • @Damien_The_Unbeliever。那是一个伪例子。在实际代码中,一列 ItemId 肯定是常见的。其他的可能相同也可能不同。

标签: c# datatable


【解决方案1】:

你可以使用 DataTable.Merge()

如果您在两个表中都有主键,那么它将对主键执行合并,否则它将直接附加所有记录。

在你的情况下,将 ItemID 作为主键。

【讨论】:

  • 合并将删除重复项。不是吗?
  • 不合并不会删除重复记录,只会根据主键用目标记录覆盖记录源记录。
  • 如果你只想追加第二个数据表行,那么不要指定 ItemID 作为主键,只需使用合并。
【解决方案2】:

使用 System.Linq.Expressions; ......

    var result1 = from row1 in dt1.AsEnumerable()                     
                 select new { Name = row1.Field<String>("Name"), Color = row1.Field<String>("Color"), Price = "" };

        var result2 = from row1 in dt2.AsEnumerable()                     
                      select new { Name = row1.Field<String>("Name"), Color = "", Price = row1.Field<String>("Price") };
        var res = result1.Concat(result2);

        foreach (var item in res)
        Console.WriteLine("{0} - {1} - {2}", item.Name, item.Color, item.Price);

【讨论】:

  • 如果我事先不知道列名怎么办
【解决方案3】:

尽管这个问题已经存在多年了,但对于正在寻找另一种方法的人来说:

        public static DataTable MergeTables(DataTable dt1, DataTable dt2)
    {
        DataTable dt3 = dt1.Clone();
        foreach (DataColumn col in dt2.Columns)
        {
            string strColumnName = col.ColumnName;
            int intColNum = 1;
            while (dt3.Columns.Contains(strColumnName))
            {
                strColumnName = string.Format("{0}_{1}", col.ColumnName, ++intColNum);
            }
            dt3.Columns.Add(strColumnName, col.DataType);
        }
        var Mergered = dt1.AsEnumerable().Zip(dt2.AsEnumerable(), (r1, r2) => r1.ItemArray.Concat(r2.ItemArray).ToArray());
        foreach (object[] rowFields in Mergered)
            dt3.Rows.Add(rowFields);

        return dt3;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多