c#如何更改数据表结构,所以列多列中的值?

标签: Linq DataTable C#
发布时间: 2017/2/28 22:57:54
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

如果我有这样的结构与数据表︰

emp_num name  status  session_id

  22    john     0       4

  22    john     0       5

  34    moh      1       3

  35    Ran      0       3

  35    Ran      0       4

如何将它转换为 datatable 像这样︰

emp_num name  status  session_id1  session_id2  session_id3  session_id4 session_id5 

  22    john     0       0             0               0            1          1

  34    moh      1       0             0               1            0          0   

  35    Ran      0       0             0               1            1          0

尝试创建自定义数据表格与循环但不是泛型,我想要如此一般的东西,这样如果我添加更多的列或次数增加我得不出范围异常。

解决方法 1:

using System.Data;
public static class DataTableExtensionMethods
{
    public static DataTable TransposeIntegerColumnIntoColumns(this DataTable dt, int indexColumnToEstablishDuplicateRows, int integerColumnIdToTranspose, string transposedColumnName)
    {
        //Protection if the column to transpose is not an integer or doesn't exist
        if (integerColumnIdToTranspose >= dt.Columns.Count) return null;
        var columnDataType = dt.Columns[integerColumnIdToTranspose].DataType;
        if (columnDataType != typeof(int)) return null;

        //Get max sessions number
        int maxColumnNumber = 0;
        foreach (DataRow dr in dt.Rows)
        {
            int? number = dr.Field<int?>(integerColumnIdToTranspose);
            if (number != null)
            {
                maxColumnNumber = Math.Max(maxColumnNumber, (int)number);
            }
        }

        //Protection if there are zero rows or the maxColumnNumber is 0
        if (dt.Rows.Count == 0 || maxColumnNumber == 0) return null;

        //Make a copy of the table so we can remove duplicate rows and add the transposed columns
        DataTable result = dt.Copy();

        //Add columns to store the session_ids
        for (int i = 1; i <= maxColumnNumber; i++)
        {
            DataColumn dc = new DataColumn(transposedColumnName + i.ToString(), typeof(int));
            dc.DefaultValue = 0;
            //Possibly make an overloaded method that supports inserting columns
            result.Columns.Add(dc);
        }

        //Remove rows with duplicated employees
        for (int i = 0; i < result.Rows.Count; i++)
        {
            int duplicateRow = GetRowIndexById(result, indexColumnToEstablishDuplicateRows, result.Rows[i][indexColumnToEstablishDuplicateRows].ToString(), i + 1);
            if (duplicateRow > -1)
            {
                result.Rows.RemoveAt(duplicateRow);
            }
        }

        //Populate the transposed columns with values in the integer Column To Transpose
        foreach (DataRow dr in dt.Rows)
        {
            int? sessionNumber = dr.Field<int?>(integerColumnIdToTranspose);
            if (sessionNumber == null) continue;
            int rowIndex = GetRowIndexById(result, indexColumnToEstablishDuplicateRows, dr[indexColumnToEstablishDuplicateRows].ToString(), 0);

            result.Rows[rowIndex][transposedColumnName + sessionNumber.ToString()] = 1; //or +=1 if you want to increment the number
        }

        //Remove the integerColumnIdToTranspose (again overload this method if you want to keep this column)
        result.Columns.RemoveAt(integerColumnIdToTranspose);

        return result;
    }

   //Net 4 implementation with optional parameter
   //private static int GetRowIndexById(DataTable dt, int indexColumnToEstablishDuplicateRows, string id, int startLookAtRow = 0)
    private static int GetRowIndexById(DataTable dt, int indexColumnToEstablishDuplicateRows, string id, int startLookAtRow)
    {
        for (int i = startLookAtRow; i < dt.Rows.Count; i++)
        {
            if (dt.Rows[i][indexColumnToEstablishDuplicateRows].ToString() == id) return i;
        }
        return -1;
    }
}

调用代码︰

private void button1_Click(object sender, EventArgs e)
{
    DataTable dt = GetData();
    DataTable result = dt.TransposeIntegerColumnIntoColumns(0, 3, "session_id");
}

private DataTable GetData()
{
    DataTable dt = new DataTable();
    dt.Columns.Add("emp_num", typeof(int));
    dt.Columns.Add("name");
    dt.Columns.Add("status", typeof(int));
    dt.Columns.Add("session_id", typeof(int));

    DataRow dr = dt.NewRow();
    dr["emp_num"] = 22;
    dr["name"] = "John";
    dr["status"] = 0;
    dr["session_id"] = 4;
    dt.Rows.Add(dr);

    dr = dt.NewRow();
    dr["emp_num"] = 22;
    dr["name"] = "John";
    dr["status"] = 0;
    dr["session_id"] = 5;
    dt.Rows.Add(dr);

    dr = dt.NewRow();
    dr["emp_num"] = 34;
    dr["name"] = "Moh";
    dr["status"] = 1;
    //dr["session_id"] = null;
    dt.Rows.Add(dr);

    dr = dt.NewRow();
    dr["emp_num"] = 35;
    dr["name"] = "Ran";
    dr["status"] = 0;
    dr["session_id"] = 3;
    dt.Rows.Add(dr);

    dr = dt.NewRow();
    dr["emp_num"] = 35;
    dr["name"] = "Ran";
    dr["status"] = 0;
    dr["session_id"] = 4;
    dt.Rows.Add(dr);

    return dt;
}

结果是︰

enter image description here

赞助商