【问题标题】:C# Merge Join DataTables (using unique id) Loaded by CSV ParserCSV Parser 加载的 C# 合并联接数据表(使用唯一 id)
【发布时间】:2019-11-09 15:17:15
【问题描述】:

我正在尝试将两个导入的 CSV 文件合并并连接到一个数据表中。 C# 对我来说是新的,但我以前在 PS 和 KSH 中做过很多次类似的事情。

数据加载正常,并像两个单独的表一样输出到控制台,但我不知道如何使用主键(wID,UserID)作为连接条件来连接每个 ShowTable() 的结果。

我尝试return Table_SalesUserData; and return Table_WifiUserData; 给出[ 'Form1.CreateTableWifi()' returns void, a return keyword must not be followed by an object expression ] 错误。

我也尝试使用:DataSet setSalesWifi = new DataSet(); 但在Button1_Click() 中会引发[ System.ArgumentNullException: ''column' argument cannot be null. Parameter name: column' ] 错误。

我认为这是因为每个的 .Columns 超出了范围。

表的创建如下所示。它们由 GenericParser 加载(代码工作正常,很长,所以没有发布)它们是 InsertTableWifi(string srcFilePathWifi)InsertTableSales(string srcFilePathSales)

我想我可以在合并数据工作时输出它,只是不知道如何将它们加入到新的 DataTable 或 DataSet 中。

有没有一种简单的方法可以将数据与我拥有的数据合并?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
using GenericParsing;

namespace GenericParserv1._1._6
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

        }
        DataTable Table_SalesUserData = new DataTable("SalesUserData ");
        DataTable Table_WifiUserData = new DataTable("WifiUserData ");
        DataSet setSalesWifi = new DataSet();

    public void CreateTableSales()
        {
            DataColumn[] colsSales ={
                      new DataColumn("UserID",typeof(String)),
                      new DataColumn("Alias",typeof(String)),
                      new DataColumn("UserType",typeof(String)),
                      new DataColumn("AccountStatus",typeof(String)),
                      new DataColumn("ChgPasswdNxtLogin",typeof(String)),
                  };
            Table_SalesUserData.Columns.AddRange(colsSales);
            Table_SalesUserData.PrimaryKey = new DataColumn[] { Table_SalesUserData.Columns["UserID"] };
            setSalesWifi.Tables.Add(Table_SalesUserData);
            //return Table_SalesUserData ;
        }

        public void CreateTableWifi()
        {

            DataColumn[] colsWifi ={
                      new DataColumn("wID",typeof(String)),
                      new DataColumn("username",typeof(String)),
                      new DataColumn("fname",typeof(String)),
                      new DataColumn("lastname",typeof(String)),
                      new DataColumn("email",typeof(String)),
                      new DataColumn("empid",typeof(String)),
                      new DataColumn("lastlogintime",typeof(String))
                  };

            Table_WifiUserData.Columns.AddRange(colsWifi);
            Table_WifiUserData.PrimaryKey = new DataColumn[] { Table_WifiUserData.Columns["wID"] };
            setSalesWifi.Tables.Add(Table_WifiUserData);
            //return Table_WifiUserData ;
        }

        public void CreateTableReport()
        {

            DataColumn[] colsMerge ={
                      new DataColumn("wID",typeof(String)),
                      new DataColumn("username",typeof(String)),
                      new DataColumn("fname",typeof(String)),
                      new DataColumn("lastname",typeof(String)),
                      new DataColumn("email",typeof(String)),
                      new DataColumn("empid",typeof(String)),
                      new DataColumn("lastlogintime",typeof(String)),
                      new DataColumn("UserID",typeof(String)),
                      new DataColumn("Alias",typeof(String)),
                      new DataColumn("UserType",typeof(String)),
                      new DataColumn("AccountStatus",typeof(String)),
                      new DataColumn("ChgPasswdNxtLogin",typeof(String)),
                  };

            Table_MergeUserData.Columns.AddRange(colsMerge);
            Table_MergeUserData.PrimaryKey = new DataColumn[] { Table_MergeUserData.Columns["wID"] };
        }

        private static void ShowTable(DataTable table)
        {
            foreach (DataColumn col in table.Columns)
            {
                Console.Write("{0,-14}", col.ColumnName);
            }
            Console.WriteLine();

            foreach (DataRow row in table.Rows)
            {
                foreach (DataColumn col in table.Columns)
                {
                    if (col.DataType.Equals(typeof(DateTime)))
                        Console.Write("{0,-14:d}", row[col]);
                    else if (col.DataType.Equals(typeof(Decimal)))
                        Console.Write("{0,-14:C}", row[col]);
                    else
                        Console.Write("{0,-14}", row[col]);
                }
                Console.WriteLine();
            }
            Console.WriteLine();
        }

      private void Button1_Click(object sender, EventArgs e)
        {
            string srcFilePathWifi = @"c:\WifiUserData.csv";
            string srcFilePathSales = @"c:\SalesUserData.csv";

            CreateTableSales();
            InsertTableSales(srcFilePathSales);

            CreateTableWifi();
            InsertTableWifi(srcFilePathWifi);

            ShowTable(Table_WifiUserData);
            ShowTable(Table_SalesUserData);

            // Set the relations between the tables and create the related constraint.
            setSalesWifi.Relations.Add("Table_WifiUserData", Table_SalesUserData.Columns["wID"], Table_SalesUserData.Columns["UserID"], true);

        }

    }
}

WifiUserData.csv:

wID           username      fname         lastname      email         empid         lastlogintime 
msmith        marysmith     mary          smith         marysmith@company.com10001         24/01/2019 14:00
jbloggs       joebloggs     joe           bloggs        joebloggs@company.com10002         10/01/2019 9:00
pgolightly    petergolightlypeter         golightly     petergolightly@company.com10003         20/01/2019 17:00
rrabbit       rogerrabbit   roger         rabbit        rogerrabbit@company.com10004         1/02/2019 14:00

SalesUserData.csv:

UserID        Alias         UserType      AccountStatus ChgPasswdNxtLogin
msmith        mary smith    Manager       No            No            
jbloggs       joe bloggs    Standard      No            No            
pgolightly    peter golightlyJunior        No            No            
rrabbit       roger rabbit  Standard      No            No   

我的目标:

UserID  Alias   UserType    AccountStatus   ChgPasswdNxtLogin   username    fname   lastname    email   empid   lastlogintime
msmith  mary smith  Manager No  No  marysmith   mary    smith   marysmith@company.com 10001 24/01/2019 14:00
jbloggs joe bloggs  Standard    No  No  joebloggs   joe bloggs  joebloggs@company.com 10002 10/01/2019 9:00
pgolightly  peter golightly Junior  No  No  petergolightly  peter   golightly   petergolightly@company.com 10003    20/01/2019 17:00
rrabbit roger rabbit    Standard    No  No  rogerrabbit roger   rabbit  rogerrabbit@company.com 10004   1/02/2019 14:00

【问题讨论】:

    标签: c# csv join merge datatable


    【解决方案1】:

    @jdweng... 再次感谢 :) 我回顾了我的浏览器历史,似乎上周我查看了超过 173 页,关于我来这里之前的问题,所以我很高兴我没有无意中通过询问浪费了任何人的时间!好的,这是基于使用#jdweng 回复的最终(完整)结果和代码。

    我将发布整个代码,因为我非常不喜欢当人们得到修复并且不发布他们想出的东西时,因此,在 173 页之后没有快乐!。也许它会帮助其他人永久解决同样的问题。

    1) 最终结果(console.writeline)如下所示:

    //------- MergeUserData--------------//
    wID           username      fname         lastname      email         empid         lastlogintime UserID        Alias         UserType      AccountStatus ChgPasswdNxtLogin
    msmith        marysmith     mary          smith         marysmith@company.com10001         24/01/2019 14:00msmith        mary smith    Manager       No            No            
    jbloggs       joebloggs     joe           bloggs        joebloggs@company.com10002         10/01/2019 9:00jbloggs       joe bloggs    Standard      No            No            
    pgolightly    petergolightlypeter         golightly     petergolightly@company.com10003         20/01/2019 17:00pgolightly    peter golightlyJunior        No            No            
    rrabbit       rogerrabbit   roger         rabbit        rogerrabbit@company.com10004         1/02/2019 14:00rrabbit       roger rabbit  Standard      No            No  
    

    2) 最终的CreateTableReport() 看起来像这样(UAT 测试通过):

     public void CreateTableReport()
            {
    
                DataColumn[] colsMerge ={
                          new DataColumn("wID",typeof(String)),      //--- Below foreach from table: sales
                          new DataColumn("username",typeof(String)), //--- Below foreach from table: wifi
                          new DataColumn("fname",typeof(String)),    //--- Below foreach from table: wifi
                          new DataColumn("lastname",typeof(String)), //--- Below foreach from table: wifi
                          new DataColumn("email",typeof(String)),    //--- Below foreach from table: wifi
                          new DataColumn("empid",typeof(String)),    //--- Below foreach from table: wifi
                          new DataColumn("lastlogintime",typeof(String)), //--- Below foreach from table: wifi
                          new DataColumn("UserID",typeof(String)),   //--- Below foreach from table: sales
                          new DataColumn("Alias",typeof(String)),    //--- Below foreach from table: sales
                          new DataColumn("UserType",typeof(String)), //--- Below foreach from table: sales
                          new DataColumn("AccountStatus",typeof(String)), //--- Below foreach from table: sales
                          new DataColumn("ChgPasswdNxtLogin",typeof(String)), //--- Below foreach from table: sales
                      };
    
                Table_MergeUserData.Columns.AddRange(colsMerge);
    
                var mergedData = (from s in Table_SalesUserData.AsEnumerable()
                                  join w in Table_WifiUserData.AsEnumerable() on s.Field<string>("UserID") equals w.Field<string>("wID")
                                  select new { sales = s, wifi = w }).ToList();
    
                foreach (var data in mergedData)
                {
                    Table_MergeUserData.Rows.Add(new object[] {
                        data.sales.Field<string>("UserID"),
                        data.wifi.Field<string>("username"),
                        data.wifi.Field<string>("fname"),
                        data.wifi.Field<string>("lastname"),
                        data.wifi.Field<string>("email"),
                        data.wifi.Field<string>("empid"),
                        data.wifi.Field<string>("lastlogintime"),
                        data.sales.Field<string>("UserID"),
                        data.sales.Field<string>("Alias"),
                        data.sales.Field<string>("UserType"),
                        data.sales.Field<string>("AccountStatus"),
                        data.sales.Field<string>("ChgPasswdNxtLogin")
                    });
    
                }
    

    3) 现在是整个 enchelade,或者无论如何拼写。

    整个 Form1.csv,使用最初添加的所有相同 CSV 文件,以及......首先导入两个 CSV 文件的 CSV Parser 代码。希望它在未来对其他人有所帮助。这一切都是在 Visual Studio 2019 社区中完成的,所有库等都在“使用”部分中。

    “Form1”是一个基本的表格,只有一个按钮“显示表格”。我从 msdn 的伟大/简单教程中得到了基本的要点:https://docs.microsoft.com/en-us/visualstudio/ide/tutorial-1-create-a-picture-viewer?view=vs-2019

    如果您像我一样是 Visual Studio 的新用户,这真的很棒。在 1x 周内,我学会了如何做那个教程,然后回归我的 linux 和 Powershell 脚本来执行 LDAP 搜索、合并数据、导入 XLS 工作簿、导出到 CSV、重新导入 CSV 文件,现在在 Stack Overflow 社区的帮助下( jdwen) 加入 dataTables 并创建一些有用的东西。幸福没有边界! :)))

    好吧,我这里就是:

    //========================================//
    //--- Useful Pages to check out ----------//
    //========================================//
    //--- https://immortalcoder.blogspot.com/2013/12/convert-csv-file-to-datatable-in-c.html
    //--- https://code.msdn.microsoft.com/How-to-create-DataTable-7abb4914
    //--- https://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader
    //--- https://www.dotnetperls.com/datatable
    //--- https://docs.microsoft.com/en-us/dotnet/api/system.data.datatable?view=netframework-4.8#examples
    
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.IO;
    using System.Text.RegularExpressions;
    using GenericParsing;
    
    
    namespace GenericParserv1._1._6
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
    
            }
    
            DataTable Table_SalesUserData = new DataTable("SalesUserData");
            DataTable Table_WifiUserData = new DataTable("WifiUserData");
            DataTable Table_MergeUserData = new DataTable("MergeUserData");
            DataSet   setSalesWifi = new DataSet();
    
    
            private static void ShowTable(DataTable table)
            {
                Console.WriteLine("//------- " + table + "--------------//");
    
                foreach (DataColumn col in table.Columns)
                {
                    Console.Write("{0,-14}", col.ColumnName);
                }
                Console.WriteLine();
    
                foreach (DataRow row in table.Rows)
                {
                    foreach (DataColumn col in table.Columns)
                    {
                        if (col.DataType.Equals(typeof(DateTime)))
                            Console.Write("{0,-14:d}", row[col]);
                        else if (col.DataType.Equals(typeof(Decimal)))
                            Console.Write("{0,-14:C}", row[col]);
                        else
                            Console.Write("{0,-14}", row[col]);
                    }
                    Console.WriteLine();
                }
                Console.WriteLine();
            }
    
    
            public void CreateTableSales()
            {
                DataColumn[] colsSales ={
                          new DataColumn("UserID",typeof(String)),
                          new DataColumn("Alias",typeof(String)),
                          new DataColumn("UserType",typeof(String)),
                          new DataColumn("AccountStatus",typeof(String)),
                          new DataColumn("ChgPasswdNxtLogin",typeof(String)),
                      };
                Table_SalesUserData.Columns.AddRange(colsSales);
                Table_SalesUserData.PrimaryKey = new DataColumn[] { Table_SalesUserData.Columns["UserID"] };
                setSalesWifi.Tables.Add(Table_SalesUserData);
    
            }
    
            public void InsertTableSales(string srcFilePathSales)
            {
                string Sales_UserID,
                Sales_Alias,
                Sales_UserType,
                Sales_AccountStatus,
                Sales_ChgPasswdNxtLogin
                ;
    
                using (GenericParser parser = new GenericParser())
                {
                    parser.SetDataSource(srcFilePathSales);
    
                    parser.ColumnDelimiter = ','; //---- For TAB DELIM USE: parser.ColumnDelimiter = "\t".ToCharArray();
                    parser.FirstRowHasHeader = true;
                    parser.SkipStartingDataRows = 0;
                    parser.MaxBufferSize = 4096;
                    parser.MaxRows = 500;
                    parser.TextQualifier = null;
    
                    while (parser.Read())
                    {
    
                        Sales_UserID = parser["UserID"];
                        Sales_Alias = parser["Alias"];
                        Sales_UserType = parser["UserType"];
                        Sales_AccountStatus = parser["AccountStatus"];
                        Sales_ChgPasswdNxtLogin = parser["ChgPasswdNxtLogin"];
    
    
                        Object[] rows = {
    
    
                            new Object[]{
                                        Sales_UserID
                                        ,Sales_Alias
                                        ,Sales_UserType
                                        ,Sales_AccountStatus
                                        ,Sales_ChgPasswdNxtLogin
                            }
                         };
    
                        foreach (Object[] row in rows)
                        {
                            Table_SalesUserData.Rows.Add(row);
                        }
    
                    }
    
                }
    
            }
    
            public void CreateTableWifi()
            {
    
                DataColumn[] colsWifi ={
                          new DataColumn("wID",typeof(String)),
                          new DataColumn("username",typeof(String)),
                          new DataColumn("fname",typeof(String)),
                          new DataColumn("lastname",typeof(String)),
                          new DataColumn("email",typeof(String)),
                          new DataColumn("empid",typeof(String)),
                          new DataColumn("lastlogintime",typeof(String))
                      };
    
                Table_WifiUserData.Columns.AddRange(colsWifi);
                Table_WifiUserData.PrimaryKey = new DataColumn[] { Table_WifiUserData.Columns["wID"] };
                setSalesWifi.Tables.Add(Table_WifiUserData);
    
            }
    
            public void InsertTableWifi(string srcFilePathWifi)
            {
    
                string Wifi_wID, Wifi_username, Wifi_fname, Wifi_lastname, Wifi_email, Wifi_empid, Wifi_lastlogintime;
    
                using (GenericParser parser = new GenericParser())
                {
                    parser.SetDataSource(srcFilePathWifi);
    
                    parser.ColumnDelimiter = ','; //---- For TAB DELIM USE: parser.ColumnDelimiter = "\t".ToCharArray();
                    parser.FirstRowHasHeader = true;
                    parser.SkipStartingDataRows = 0;
                    parser.MaxBufferSize = 4096;
                    parser.MaxRows = 500;
                    parser.TextQualifier = null;
    
                    while (parser.Read())
                    {
    
                        Wifi_wID = parser["wID"];
                        Wifi_username = parser["username"];
                        Wifi_fname = parser["fname"];
                        Wifi_lastname = parser["lastname"];
                        Wifi_email = parser["email"];
                        Wifi_empid = parser["empid"];
                        Wifi_lastlogintime = parser["lastlogintime"];
    
                        Object[] rows = {
    
    
                            new Object[]{
                                        Wifi_wID
                                        ,Wifi_username
                                        ,Wifi_fname
                                        ,Wifi_lastname
                                        ,Wifi_email
                                        ,Wifi_empid
                                        ,Wifi_lastlogintime
                            }
                         };
    
                        foreach (Object[] row in rows)
                        {
                            Table_WifiUserData.Rows.Add(row);
                        }
    
                    }
    
                }
            }
    
             public void CreateTableReport()
            {
    
                DataColumn[] colsMerge ={
                          new DataColumn("wID",typeof(String)),      //--- Below foreach from table: sales
                          new DataColumn("username",typeof(String)), //--- Below foreach from table: wifi
                          new DataColumn("fname",typeof(String)),    //--- Below foreach from table: wifi
                          new DataColumn("lastname",typeof(String)), //--- Below foreach from table: wifi
                          new DataColumn("email",typeof(String)),    //--- Below foreach from table: wifi
                          new DataColumn("empid",typeof(String)),    //--- Below foreach from table: wifi
                          new DataColumn("lastlogintime",typeof(String)), //--- Below foreach from table: wifi
                          new DataColumn("UserID",typeof(String)),   //--- Below foreach from table: sales
                          new DataColumn("Alias",typeof(String)),    //--- Below foreach from table: sales
                          new DataColumn("UserType",typeof(String)), //--- Below foreach from table: sales
                          new DataColumn("AccountStatus",typeof(String)), //--- Below foreach from table: sales
                          new DataColumn("ChgPasswdNxtLogin",typeof(String)), //--- Below foreach from table: sales
                      };
    
                Table_MergeUserData.Columns.AddRange(colsMerge);
    
                var mergedData = (from s in Table_SalesUserData.AsEnumerable()
                                  join w in Table_WifiUserData.AsEnumerable() on s.Field<string>("UserID") equals w.Field<string>("wID")
                                  select new { sales = s, wifi = w }).ToList();
    
                foreach (var data in mergedData)
                {
                    Table_MergeUserData.Rows.Add(new object[] {
                        data.sales.Field<string>("UserID"),
                        data.wifi.Field<string>("username"),
                        data.wifi.Field<string>("fname"),
                        data.wifi.Field<string>("lastname"),
                        data.wifi.Field<string>("email"),
                        data.wifi.Field<string>("empid"),
                        data.wifi.Field<string>("lastlogintime"),
                        data.sales.Field<string>("UserID"),
                        data.sales.Field<string>("Alias"),
                        data.sales.Field<string>("UserType"),
                        data.sales.Field<string>("AccountStatus"),
                        data.sales.Field<string>("ChgPasswdNxtLogin")
                    });
    
                }
    
            }
    
    
            private void Button1_Click(object sender, EventArgs e)
            {
                string srcFilePathWifi = @"C:\WifiUserData.csv";
                string srcFilePathSales = @"C:\SalesUserData.csv";
    
                CreateTableSales();
                InsertTableSales(srcFilePathSales);
    
                CreateTableWifi();
                InsertTableWifi(srcFilePathWifi);
    
                ShowTable(Table_WifiUserData);
                ShowTable(Table_SalesUserData);
    
                CreateTableReport();
                ShowTable(Table_MergeUserData);
    
            }
        }
    }
    
    

    【讨论】:

      【解决方案2】:

      尝试关注。我在合并表中放了一列,其余的留给你。 :

             public void CreateTableReport()
              {
      
                  DataColumn[] colsMerge ={
                            new DataColumn("wID",typeof(String)),
                            new DataColumn("username",typeof(String)),
                            new DataColumn("fname",typeof(String)),
                            new DataColumn("lastname",typeof(String)),
                            new DataColumn("email",typeof(String)),
                            new DataColumn("empid",typeof(String)),
                            new DataColumn("lastlogintime",typeof(String)),
                            new DataColumn("UserID",typeof(String)),
                            new DataColumn("Alias",typeof(String)),
                            new DataColumn("UserType",typeof(String)),
                            new DataColumn("AccountStatus",typeof(String)),
                            new DataColumn("ChgPasswdNxtLogin",typeof(String)),
                        };
      
                  Table_MergeUserData.Columns.AddRange(colsMerge);
      
                  var mergedData = (from s in Table_SalesUserData.AsEnumerable()
                                    join w in Table_WifiUserData.AsEnumerable() on s.Field<string>("UserID") equals w.Field<string>("wID")
                                    select new { sales = s, wifi = w }).ToList();
      
                  foreach (var data in mergedData)
                  {
                      Table_MergeUserData.Rows.Add(new object[] {
                          data.sales.Field<string>("wID")
                      });
                  }
      
              }
      

      【讨论】:

      • #jdweng ...你我的朋友,我确实不是轻描淡写地这么说,正如你将在下面看到的,我最尊重地使用这个词。它工作得很好。我已经扩展它以生成整个表格作为两者的合并,完全符合所需的格式。 TBH,在 20 多年的编码脚本中,我记得只在网上这样问过 7 次。因此,当我提供帮助时,我非常尊重所传递的信息以及无私的人帮助随机陌生人所花费的时间。 slow bow and smile to you。谢谢。让我在下面发布最终脚本,因为这个字段对我能说的内容非常短。 :)))))
      • 附言。我试图给你“投票”#jdweng 但是:``` 感谢您的反馈!声望低于 15 人的投票将被记录,但不会更改公开显示的帖子得分。 ```
      • 您可能想查看 msdn 的 linq 示例,它具有 join 方法:code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b
      • PPS...任何有上帝身份的人请在他的重播上投票#jdweng,它完美运行...谢谢!
      猜你喜欢
      • 1970-01-01
      • 2012-06-25
      • 1970-01-01
      • 1970-01-01
      • 2020-12-15
      • 2021-05-05
      • 2017-08-07
      • 2019-08-24
      • 1970-01-01
      相关资源
      最近更新 更多