zoukankan      html  css  js  c++  java
  • C#代码中实现两个表(DataTable)的关联查询(JOIN)

    参考网址: https://www.cnblogs.com/xuxiaona/p/4000344.html

    之前通常都是使用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);
                }
            }
        }
    }
    复制代码
  • 相关阅读:
    NCNN优化实时面部关键点检测
    使用 div 标签 contenteditable="true" 实现一个 聊天框,支持 Ctrl + v 粘贴图片
    《精益创业》读书总结
    DATAX使用
    canal增量同步原理以及使用说明
    element rules required 自定义表达式
    JavaScript 数组映射,重新整理
    wangeditor遮挡其他控件
    多个axios按顺序执行
    .NET Core 中基于 IHostedService 实现后台定时任务
  • 原文地址:https://www.cnblogs.com/bruce1992/p/15309433.html
Copyright © 2011-2022 走看看