Как объединить два столбца в наборе данных? - PullRequest
2 голосов
/ 19 января 2009

Ранее я спрашивал о вставке столбца в набор данных . У меня сейчас похожий вопрос ... а именно, объединение двух или более столбцов в один столбец.

Допустим, у меня есть следующий набор данных:

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));

Мне нужно объединить столбцы «имя» и «фамилия» в один столбец с именем «имя».

Было бы лучше для меня создать метод, который объединяет два столбца вместе, или более общий метод, который можно использовать для объединения нескольких столбцов вместе?

Моя идея - создать обобщенный метод, подобный следующему:

MergeColumns (формат строки, строка mergedColumn, DataTable dt, строка params [] columnsToMerge)

Пользователь предоставляет следующий формат: "{0} {1}"

mergedColumn - это имя нового столбца ... но он должен совпадать с одним из столбцов, которые будут объединены, потому что в моем случае из реального мира я объединяю "name" и "дали_имя" в "имя" ... но я все еще хочу иметь возможность использовать его, если мне когда-нибудь понадобится объединить "улицу", "город", "штат", "почтовый индекс" и т. д. в столбец с именем "адрес".

Я думаю, что это будет использовано следующим образом:

MergeColumns ("{0} {1}", "name", dataTable, "firstname", "lastname");

учитывая вышеупомянутый набор данных, я ожидаю, что результирующий набор данных будет выглядеть следующим образом:

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 ]

5 голосов
/ 19 января 2009
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() );
    }


}
1 голос
/ 19 января 2009

альтернативно, вы можете сделать это:

    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());


    }
1 голос
/ 19 января 2009

мне кажется, что это должно происходить на уровне данных, а не на уровне логики. предположительно, потребитель набора данных знает, какие данные ему нужны, и может явно запросить их у хранилища данных, не манипулируя наборами данных.

в сценарии базы данных я, по сути, поддерживаю подход с несколькими хранимыми процедурами, и потребитель набора данных будет извлекать данные из соответствующего.

1 голос
/ 19 января 2009

Если набор данных достаточно конкретен, метод MergeName () подойдет. Это особенно верно, если вы не думаете, что будете использовать его более одного раза. Универсальный метод потребует значительно больше работы, но может стоить того, если вы делаете много слияния.

Некоторые вещи, которые я могу придумать из головы, с которыми вам придется иметь дело:

  • Одна проблема, с которой вы можете столкнуться, это проверка типов; что произойдет, если пользователь захочет объединить поле даты или числовое поле.
  • Что происходит со старыми полями? Они останутся или будут удалены? Если вы используете это как прямой источник данных, вы можете удалить оставшиеся столбцы, так что какой-то флаг RemoveOldColumns может быть хорошей идеей.
0 голосов
/ 17 сентября 2018

метод расширения С возможностью выбора разделитель и положение ,

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");
0 голосов
/ 03 июля 2015
string result = string.Join(",", dtTotalQuery.AsEnumerable().Select(row => dtTotalQuery.Rows[0].ItemArray[0] + " " + dtTotalQuery.Rows[0].ItemArray[1]));
0 голосов
/ 15 ноября 2011

Это было именно моим требованием, и после долгих поисков я решил, что лучше создать свой собственный набор данных и использовать его в качестве источника данных для ListBox или 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 - это набор данных, содержащий основную таблицу возврата процедуры.

0 голосов
/ 19 января 2009
        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"]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...