none
合并3个DataTable到一个新DataTable RRS feed

  • 问题

  • 从3个数据库查询出3个DataTable(TB_A,TB_,B,TB_C)
    如果TB_A的ItemCode等于TB_B的ItemCode,把TB_B的QTY加到新DataTable(名字:New_DataTable)里的TB_B_QTY这栏
    如果TB_A的ItemCode不等于TB_B的ItemCode,那么在New_DataTable加入TB_B这一行的ItemCOde,QTY
    TB_C也是同样处理.

    TB_A结构:
    ItemCode    ItemName    Qty
    A001             你好            10
    B001   大家好             30


    TB_B结构:
    ItemCode    ItemName    Qty
    A001             你好            10
    A003             不用谢                20


    TB_C结构:
    ItemCode    ItemName    Qty
    A002             谢谢                20
    B001   大家好             30

    最后结果New_DataTable
    TB_A结构:
    ItemCode    ItemName    Qty         TB_B_QTY          TB_C_QTY 
    A001             你好            10             10                         N/A
    A002            谢谢                N/A            20                          20
    A003             不用谢           N/A             20                        N/A
    B001   大家好             N/A             N/A                        30

    请问取得这样的结果,是不是用LINQ的join?
    2016年8月11日 9:53

答案

  • 你好,

    如果使用LINQ的话,我建议你可以先使用Union方法将3个table合并起来得到所有的ItemCode和ItemName(注意去除重复项)。然后使用LINQ查询结果,在Select语句中根据DataTable的值设置Qty列的值。

    你可以参考下面的代码:

                DataTable dt = new DataTable();
                dt.Columns.Add("ItemCode", typeof(string));
                dt.Columns.Add("ItemName", typeof(string));
                dt.Columns.Add("Qty", typeof(string));
                dt.PrimaryKey = new DataColumn[] { dt.Columns[0] };
    
                //Add data for dt
                dt.Rows.Add("A001", "你好", "10");
                dt.Rows.Add("B001", "大家好", "30");
    
                //clone the table into dt2 and mock new data for dt2
                DataTable dt2 = dt.Clone();
                dt2.TableName = "dt2";
                dt2.Rows.Add("A001", "你好", "10");
                dt2.Rows.Add("A003", "不用谢", "20");
    
                //clone the table into dt2 and mock new data for dt2
                DataTable dt3 = dt.Clone();
                dt3.TableName = "dt3";
                dt3.Rows.Add("A002", "谢谢", "20");
                dt3.Rows.Add("B001", "大家好", "30");
    
                //合并表,去除重复项
                var query = dt.AsEnumerable().Union(dt2.AsEnumerable()).Union(dt3.AsEnumerable()).Select(c => new { ItemCode = c.Field<string>("ItemCode"), ItemName = c.Field<string>("ItemName")}).Distinct().ToList();
                //result:            
                //ItemCode ItemName
                //A001      你好 
                //B001      大家好 
                //A003      不用谢 
                //A002      谢谢 
                var query2 = from qq in query
                             select new
                             {
                                 ItemCode = qq.ItemCode,
                                 ItemName = qq.ItemName,
                                 Qty = dt.AsEnumerable().Where(c=>c.Field<string>("ItemCode") == qq.ItemCode).Select(c=>c.Field<string>("Qty")).FirstOrDefault() ??"N/A",
                                 TB_B_Qty = dt2.AsEnumerable().Where(c => c.Field<string>("ItemCode") == qq.ItemCode).Select(c => c.Field<string>("Qty")).FirstOrDefault() ?? "N/A",
                                 TB_C_Qty = dt3.AsEnumerable().Where(c => c.Field<string>("ItemCode") == qq.ItemCode).Select(c => c.Field<string>("Qty")).FirstOrDefault() ?? "N/A",
                             };
    
    
                GridView1.DataSource = query2.ToList();
                GridView1.DataBind();
    
                //output:
                //ItemCode  ItemName    Qty     TB_B_Qty    TB_C_Qty
                //A001      你好        10        10          N/A 
                //B001      大家好      30        N/A         30 
                //A003      不用谢      N/A       20          N/A 
                //A002      谢谢        N/A       N/A         20 

    2016年8月16日 6:14
    版主

全部回复

  • 请教给点思路.
    2016年8月12日 3:52

  • 就算用linq好像也很麻烦,

    比较原始的方法,先获取所有ItemCode,

    新建包含ItemCode    ItemName    Qty         TB_B_QTY          TB_C_QTY 的表
    对每个表遍历,然后填到相应位置

    2016年8月12日 9:46
  • namespace ConsoleApplication1
    {
        using System;
        using System.Data;
     
        class Program
        {
            /// <summary>
            /// Merge the different row from dt2 or dt3
            /// </summary>
            static void MergeRows(DataTable newTable, DataTable originalTable, string tbName)
            {
                DataRow foundRow = null;
     
                foreach (DataRow row in newTable.Rows)
                {
                    foundRow = originalTable.Rows.Find(row["ItemCode"].ToString());
                    if (foundRow != null)
                    {
                        if (tbName == "dt2")
                        {
                            foundRow["TB_B_Qty"= row["Qty"].ToString();
                        }
                        else if (tbName == "dt3")
                        {
                            foundRow["TB_C_Qty"= row["Qty"].ToString();
                        }
                    }
                    else
                    {
                        originalTable.ImportRow(row);
                        originalTable.Rows[originalTable.Rows.Count - 1]["Qty"= "N/A";
                        if (tbName == "dt2")
                        {
                            originalTable.Rows[originalTable.Rows.Count - 1]["TB_B_Qty"= row["Qty"].ToString();
                            originalTable.Rows[originalTable.Rows.Count - 1]["TB_C_Qty"= "N/A";
                        }
                        else if (tbName == "dt3")
                        {
                            originalTable.Rows[originalTable.Rows.Count - 1]["TB_C_Qty"= row["Qty"].ToString();
                            originalTable.Rows[originalTable.Rows.Count - 1]["TB_B_Qty"= "N/A";
                        }
                    }
                }
     
            }
            static void Main(string[] args)
            {
                DataTable dt = new DataTable();
                dt.Columns.Add("ItemCode"typeof(string));
                dt.Columns.Add("ItemName"typeof(string));
                dt.Columns.Add("Qty"typeof(string));
                dt.PrimaryKey = new DataColumn[] { dt.Columns[0] };
     
                //Add data for dt
                dt.Rows.Add("A001""你好""10");
                dt.Rows.Add("B001""大家好""30");
     
                //clone the table into dt2 and mock new data for dt2
                DataTable dt2 = dt.Clone();
                dt2.TableName = "dt2";
                dt2.Rows.Add("A001""你好""10");
                dt2.Rows.Add("A003""不用谢""20");
     
                //clone the table into dt2 and mock new data for dt2
                DataTable dt3 = dt.Clone();
                dt3.TableName = "dt3";
                dt3.Rows.Add("A002""谢谢""20");
                dt3.Rows.Add("B001""大家好""30");
     
                //Create a new table for the final result
                DataTable result = new DataTable();
                result.Columns.Add("ItemCode"typeof(string));
                result.Columns.Add("ItemName"typeof(string));
                result.Columns.Add("Qty"typeof(string));
                result.Columns.Add("TB_B_Qty"typeof(string));
                result.Columns.Add("TB_C_Qty"typeof(string));
                result.PrimaryKey = new DataColumn[] { result.Columns[0] };
     
                foreach (DataRow row in dt.Rows)
                {
                    //Do Insert values into result for dt
                    result.ImportRow(row);
                    result.Rows[result.Rows.Count - 1]["TB_B_Qty"= "N/A";
                    result.Rows[result.Rows.Count - 1]["TB_C_Qty"= "N/A";
                }
     
                MergeRows(dt2, result, dt2.TableName);
                MergeRows(dt3, result, dt3.TableName);
     
                DataView dv = new DataView(result);
                dv.Sort = "ItemCode";
                result = dv.ToTable();
                Console.ReadLine();
            }
        }
    }

    ASP.NET Forum
    StackOverFlow
    FreeRice Donate
    Issues to report
    Free Tech Books Search and Download

    2016年8月13日 11:38
  • 你好,

    如果使用LINQ的话,我建议你可以先使用Union方法将3个table合并起来得到所有的ItemCode和ItemName(注意去除重复项)。然后使用LINQ查询结果,在Select语句中根据DataTable的值设置Qty列的值。

    你可以参考下面的代码:

                DataTable dt = new DataTable();
                dt.Columns.Add("ItemCode", typeof(string));
                dt.Columns.Add("ItemName", typeof(string));
                dt.Columns.Add("Qty", typeof(string));
                dt.PrimaryKey = new DataColumn[] { dt.Columns[0] };
    
                //Add data for dt
                dt.Rows.Add("A001", "你好", "10");
                dt.Rows.Add("B001", "大家好", "30");
    
                //clone the table into dt2 and mock new data for dt2
                DataTable dt2 = dt.Clone();
                dt2.TableName = "dt2";
                dt2.Rows.Add("A001", "你好", "10");
                dt2.Rows.Add("A003", "不用谢", "20");
    
                //clone the table into dt2 and mock new data for dt2
                DataTable dt3 = dt.Clone();
                dt3.TableName = "dt3";
                dt3.Rows.Add("A002", "谢谢", "20");
                dt3.Rows.Add("B001", "大家好", "30");
    
                //合并表,去除重复项
                var query = dt.AsEnumerable().Union(dt2.AsEnumerable()).Union(dt3.AsEnumerable()).Select(c => new { ItemCode = c.Field<string>("ItemCode"), ItemName = c.Field<string>("ItemName")}).Distinct().ToList();
                //result:            
                //ItemCode ItemName
                //A001      你好 
                //B001      大家好 
                //A003      不用谢 
                //A002      谢谢 
                var query2 = from qq in query
                             select new
                             {
                                 ItemCode = qq.ItemCode,
                                 ItemName = qq.ItemName,
                                 Qty = dt.AsEnumerable().Where(c=>c.Field<string>("ItemCode") == qq.ItemCode).Select(c=>c.Field<string>("Qty")).FirstOrDefault() ??"N/A",
                                 TB_B_Qty = dt2.AsEnumerable().Where(c => c.Field<string>("ItemCode") == qq.ItemCode).Select(c => c.Field<string>("Qty")).FirstOrDefault() ?? "N/A",
                                 TB_C_Qty = dt3.AsEnumerable().Where(c => c.Field<string>("ItemCode") == qq.ItemCode).Select(c => c.Field<string>("Qty")).FirstOrDefault() ?? "N/A",
                             };
    
    
                GridView1.DataSource = query2.ToList();
                GridView1.DataBind();
    
                //output:
                //ItemCode  ItemName    Qty     TB_B_Qty    TB_C_Qty
                //A001      你好        10        10          N/A 
                //B001      大家好      30        N/A         30 
                //A003      不用谢      N/A       20          N/A 
                //A002      谢谢        N/A       N/A         20 

    2016年8月16日 6:14
    版主