代码之家  ›  专栏  ›  技术社区  ›  mezoid

如何合并数据集中的两列?

  •  2
  • mezoid  · 技术社区  · 16 年前

    以前我问过 inserting a column into a dataset . 我现在有一个类似的问题……即将两个或多个列合并为一个列。

    假设我有以下数据集:

    DataSet ds = new DataSet();
    ds.Tables.Add(new DataTable());
    ds.Tables[0].Columns.Add("id", typeof(int));
    ds.Tables[0].Columns.Add("firstname", typeof(string));
    ds.Tables[0].Columns.Add("lastname", typeof(string));
    

    我需要将“firstname”和“lastname”列合并为一个名为“name”的列。

    我最好创建一个将两列合并在一起的方法,还是创建一个更通用的方法,用于将多列合并在一起?

    我的想法是创建一个类似以下的通用方法:

    mergecolumns(字符串格式,字符串mergedcolumn,数据表dt,参数string[]columnstomerge)

    用户提供如下格式:“0 1”

    MergedColumn是新列的名称……但它必须能够与将要合并的列之一相同,因为在现实世界中,我将“名称”和“给定名称”合并为“名称”…但如果需要将“街道”、“城市”、“州”、“邮政编码”等合并为“地址”列,我仍然希望能够使用它。

    我认为这将被使用的方式如下:

    合并列(“0_1”,“名称”,数据表,“名字”,“姓氏”);

    鉴于上述数据集,我希望结果数据集如下所示:

    DataSet ds = new DataSet();
    ds.Tables.Add(new DataTable());
    ds.Tables[0].Columns.Add("id", typeof(int));
    ds.Tables[0].Columns.Add("name", typeof(string));
    

    这似乎是一个合理的方法吗?这样的方法已经存在了吗?我不想重新发明轮子。另外,我是否正在创建一个比我现在实际需要的功能更多的方法?

    8 回复  |  直到 16 年前
        1
  •  1
  •   Jason    16 年前

    在我看来,这应该发生在数据层,而不是逻辑层。假定数据集使用者知道它需要什么数据,并且可以从数据存储中显式地请求它,而不必操纵数据集。

    在一个数据库场景中,我基本上提出了一种多存储过程方法,数据集使用者将从适当的方法中检索数据。

        2
  •  5
  •   Michael Buen    16 年前
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
    
    
            DataSet ds = new DataSet();
            ds.Tables.Add(new DataTable());
            ds.Tables[0].Columns.Add("id", typeof(int));
            ds.Tables[0].Columns.Add("firstname", typeof(string));
            ds.Tables[0].Columns.Add("lastname", typeof(string));
    
    
            ds.Tables[0].Rows.Add(1,"torvalds", "linus");
            ds.Tables[0].Rows.Add(2,"lennon", "john");            
    
    
            ds.Tables[0].MergeColumns("name", "lastname", "firstname");
    
            foreach (DataRow dr in ds.Tables[0].Rows)
                MessageBox.Show(dr["name"].ToString());
    
    
        }
    
    
    }
    
    public static class Helper
    {
        public static void MergeColumns(this DataTable t, string newColumn, params string[] columnsToMerge)
        {
            t.Columns.Add(newColumn, typeof(string));
    
            var sb = new StringBuilder();
    
            sb.Append("{0}, ");
            for (int i = 1; i < columnsToMerge.Length; ++i)
                sb.Append("{" + i.ToString() + "}");
    
            string format = sb.ToString();
    
            foreach(DataRow r in t.Rows)
                r[newColumn] = string.Format(format, columnsToMerge.Select(col => r[col]).ToArray() );
        }
    
    
    }
    
        3
  •  1
  •   Soviut    16 年前

    如果数据集足够具体,则可以使用mergename()方法。如果你不认为你会在不止一个地方使用它,这一点尤其正确。一个通用方法将需要大量的工作,但是如果您进行大量的合并,那么它可能是值得的。

    我能想到的一些你必须处理的事情:

    • 您可能遇到的一个问题是类型检查;如果用户希望合并日期字段或数字字段,会发生什么情况。
    • 老田地怎么了?它们是保留还是删除?如果将其用作直接数据源,则可能需要删除剩余的列,因此 RemoveOldColumns 旗子也许是个好主意。
        4
  •  1
  •   Michael Buen    16 年前

    或者,您可以这样做:

        public Form1()
        {
            InitializeComponent();
    
    
            DataSet ds = new DataSet();
            ds.Tables.Add(new DataTable());
            ds.Tables[0].Columns.Add("id", typeof(int));
            ds.Tables[0].Columns.Add("firstname", typeof(string));
            ds.Tables[0].Columns.Add("lastname", typeof(string));
    
    
            ds.Tables[0].Rows.Add(1,"torvalds", "linus");
            ds.Tables[0].Rows.Add(2,"lennon", "john");    
    
    
            ds.Tables[0].Columns.Add("name", typeof(string), "lastname + ', ' + firstname"); 
    
    
            foreach (DataRow dr in ds.Tables[0].Rows)
                MessageBox.Show(dr["name"].ToString());
    
    
        }
    
        5
  •  0
  •   Michael Buen    16 年前
            DataSet ds = new DataSet();
            ds.Tables.Add(new DataTable());
            ds.Tables[0].Columns.Add("id", typeof(int));
            ds.Tables[0].Columns.Add("firstname", typeof(string));
            ds.Tables[0].Columns.Add("lastname", typeof(string));
    
    
            ds.Tables[0].Rows.Add(1,"torvalds", "linus");
            ds.Tables[0].Rows.Add(2,"lennon", "john");
    
    
            ds.Tables[0].Columns.Add("name", typeof(string));
            foreach (DataRow dr in ds.Tables[0].Rows) dr["name"] = dr["lastname"] + ", " + dr["firstname"];
    
    
            foreach (DataRow dr in ds.Tables[0].Rows)
                MessageBox.Show(dr["name"]);
    
        6
  •  0
  •   CharlesB Craig McQueen    13 年前

    这正是我的要求,经过大量的搜索,我最终决定最好创建自己的数据表,并将其用作列表框或DropDownList的数据源,以需要的为准。

    DataTable dt = new DataTable();
    dt.Columns.Add("Test",typeof(String));
    foreach (DataRow r in ds.Tables[0].Rows)
    {
      DataRow dr = dt.NewRow();
      dr["Test"] = r["LastName"] + " ," + r["firstName"];
      dt.Rows.Add(dr);
    }
    

    在这里 ds 是包含过程的主返回表的数据集。

        7
  •  0
  •   sqluser    10 年前
    string result = string.Join(",", dtTotalQuery.AsEnumerable().Select(row => dtTotalQuery.Rows[0].ItemArray[0] + " " + dtTotalQuery.Rows[0].ItemArray[1]));
    
        8
  •  0
  •   Sameera R. Saleh Masum    7 年前

    可选择的扩展方法 分离器 位置 ,

    public static class Helper
    {
        public static void MergeColumns(this DataTable t, string newColumn, params string[] columnsToMerge)
        {
            t.Columns.Add(newColumn, typeof(string));
    
            var sb = new StringBuilder();
    
            sb.Append("{0}, ");
            for (int i = 1; i < columnsToMerge.Length; ++i)
                sb.Append("{" + i.ToString() + "}");
    
            string format = sb.ToString();
    
            foreach(DataRow r in t.Rows)
                r[newColumn] = string.Format(format, columnsToMerge.Select(col => r[col]).ToArray() );
        }
    }
    

    用法

    //DataTable dt
    dt.MergeColumns("name", 0, " ", "lastname", "firstname");
    
    推荐文章