C#代碼中實現兩個表(DataTable)的關聯查詢(JOIN)

以前一般都是使用SQL直接從數據庫中取出表1和表2關聯查詢後的數據,只須要用一個JOIN就能夠了,很是方便。近日遇到一種狀況,兩個表中的數據已經取到代碼中,須要在代碼中將這兩個表關聯起來,並獲得它們橫向拼在一塊兒以後的完整數據。數據庫

如:表1--商品信息表(dtHead),存放商品的ID和名稱,表結構和數據以下:性能

 

 

 

     表2--商品數量及金額表(dtTail),存放商品的數量、金額,表結構和數據以下:測試

如今要獲得表1和表2橫向拼接起來的表(DtAll),結果以下:this

 

在C#代碼中,要將這兩個表拼接起來,有不少笨辦法,例如循環獲取數據一條條拼起來,但在數據量大的狀況下會影響性能,在字段多的時候也須要寫一大堆給每一個字段依次賦值的代碼。spa

使用LINQ能夠幫助解決這一問題。下面提供了兩種方案:blog

方案一:當可以肯定DtAll表的字段,而且字段不是不少的狀況下,能夠顯式寫出:事件

           var query1 =
                from rHead in dtHead.AsEnumerable()
                from rTail in dtTail.AsEnumerable()
                where rHead.Field<Int32>("GoodID") == rTail.Field<Int32>("GoodID")
                select new 
                {
                    GoodID = rHead.Field<Int32>("GoodID"),
                    GoodName = rHead.Field<String>("GoodName"),
                    Num = rTail.Field<Int32>("Num"),
                    Money = rTail.Field<Int32>("Money")
                };

            DataTable dtNew = DtAll.Copy();
            foreach (var obj in query1)
            {
                dtNew.Rows.Add(obj.GoodID, obj.GoodName, obj.Num, obj.Money);
            }

  

其中DtAll的表結構已經事先建立好了,在下面會給出全部代碼。ip

 

方案二:LINQ提供了與SQL中相似的JOIN方法。而且當字段不少的狀況下,每個字段都在select new中寫出來比較麻煩,可使用以下的方式:it

            var query =
                from rHead in dtHead.AsEnumerable()
                join rTail in dtTail.AsEnumerable()
                on rHead.Field<Int32>("GoodID") equals rTail.Field<Int32>("GoodID")
                select rHead.ItemArray.Concat(rTail.ItemArray.Skip(1));

            foreach (var obj in query)
            {
                DataRow dr = DtAll.NewRow();
                dr.ItemArray = obj.ToArray();
                DtAll.Rows.Add(dr);
            }

  

使用Concat將表1和表2的字段拼接起來,做爲總表DtAll的字段,但因爲表一、表2中都存在字段GoodID,不能在表中出現重複的字段,所以使用Skip(1)跳過表2中的第一個字段GoodID。io

 

下面給出這個小例子完整的代碼(不包括窗體,窗體上很簡單,只有一個按鈕)

首先寫入測試數據:把表一、表2建立起來並插入如上圖所示的數據(實際狀況是表一、表2經過其餘渠道直接獲取到代碼中的)

而後在單擊「鏈接」按鈕時,獲得表一、表2橫向鏈接後的表:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data;

namespace WpfApplication1
{
    /// <summary>
    /// MainWindow.xaml 的交互邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        DataTable dtHead = new DataTable();
        DataTable dtTail = new DataTable();
        DataTable DtAll = new DataTable();

        public MainWindow()
        {
            InitializeComponent();

            this.AddData();
        }

        /// <summary>
        /// 建立表結構,添加數據源
        /// </summary>
        private void AddData()
        {
            dtHead.Columns.Add("GoodID", typeof(Int32));
            dtHead.Columns.Add("GoodName", typeof(String));

            dtTail.Columns.Add("GoodID", typeof(Int32));
            dtTail.Columns.Add("Num", typeof(Int32));
            dtTail.Columns.Add("Money", typeof(Int32));

            DtAll.Columns.Add("GoodID", typeof(Int32));
            DtAll.Columns.Add("GoodName", typeof(String));
            DtAll.Columns.Add("Num", typeof(Int32));
            DtAll.Columns.Add("Money", typeof(Int32));

            this.AddRow(1, "青島純生", 10, 30);
            this.AddRow(2, "哈爾濱啤酒", 5, 20);
        }

        /// <summary>
        /// 添加數據
        /// </summary>
        /// <param name="goodID"></param>
        /// <param name="goodName"></param>
        /// <param name="num1"></param>
        /// <param name="num2"></param>
        private void AddRow(Int32 goodID, String goodName, Int32 num1,Int32 num2)
        {
            DataRow drH = dtHead.NewRow();
            drH["GoodID"] = goodID;
            drH["GoodName"] = goodName;
            dtHead.Rows.Add(drH);

            DataRow drT = dtTail.NewRow();
            drT["GoodID"] = goodID;
            drT["Num"] = num1;
            drT["Money"] = num2;
            dtTail.Rows.Add(drT);
        }

        /// <summary>
        /// 「鏈接」按鈕單擊事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Join_Click(object sender, RoutedEventArgs e)
        {
            //方案一
            var query1 =
                from rHead in dtHead.AsEnumerable()
                from rTail in dtTail.AsEnumerable()
                where rHead.Field<Int32>("GoodID") == rTail.Field<Int32>("GoodID")
                select new 
                {
                    GoodID = rHead.Field<Int32>("GoodID"),
                    GoodName = rHead.Field<String>("GoodName"),
                    Num = rTail.Field<Int32>("Num"),
                    Money = rTail.Field<Int32>("Money")
                };

            DataTable dtNew = DtAll.Copy();
            foreach (var obj in query1)
            {
                dtNew.Rows.Add(obj.GoodID, obj.GoodName, obj.Num, obj.Money);
            }

            //方案二
            var query =
                from rHead in dtHead.AsEnumerable()
                join rTail in dtTail.AsEnumerable()
                on rHead.Field<Int32>("GoodID") equals rTail.Field<Int32>("GoodID")
                select rHead.ItemArray.Concat(rTail.ItemArray.Skip(1));

            foreach (var obj in query)
            {
                DataRow dr = DtAll.NewRow();
                dr.ItemArray = obj.ToArray();
                DtAll.Rows.Add(dr);
            }
        }
    }
}

  

 

 

相關文章
相關標籤/搜索