之前通常都是使用SQL直接從數據庫中取出表1和表2關聯查詢后的數據,只需要用一個JOIN就可以了,非常方便。近日遇到一種情況,兩個表中的數據已經取到代碼中,需要在代碼中將這兩個表關聯起來,並得到它們橫向拼在一起之后的完整數據。
如:表1--商品信息表(dtHead),存放商品的ID和名稱,表結構和數據如下:
表2--商品數量及金額表(dtTail),存放商品的數量、金額,表結構和數據如下:


現在要得到表1和表2橫向拼接起來的表(DtAll),結果如下:
在C#代碼中,要將這兩個表拼接起來,有很多笨辦法,例如循環獲取數據一條條拼起來,但在數據量大的情況下會影響性能,在字段多的時候也需要寫一大堆給每個字段依次賦值的代碼。
使用LINQ可以幫助解決這一問題。下面提供了兩種方案:
方案一:當能夠確定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的表結構已經事先創建好了,在下面會給出所有代碼。
方案二:LINQ提供了與SQL中類似的JOIN方法。並且當字段很多的情況下,每一個字段都在select new中寫出來比較麻煩,可以使用如下的方式:
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的字段,但由於表1、表2中都存在字段GoodID,不能在表中出現重復的字段,因此使用Skip(1)跳過表2中的第一個字段GoodID。
下面給出這個小例子完整的代碼(不包括窗體,窗體上很簡單,只有一個按鈕)
首先寫入測試數據:把表1、表2創建起來並插入如上圖所示的數據(實際情況是表1、表2通過其他渠道直接獲取到代碼中的)
然后在單擊“連接”按鈕時,得到表1、表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); } } } }


