Linq 实现 DataTable 行转列

前几天写了一篇sqlserver  行转列http://www.cnblogs.com/li-peng/archive/2012/02/01/2334973.html

由于工作需要,要把查出来的DataTable实现 行转列,

正好这一阵子在用Linq 就做了一个行转列的小例 子

转换前的table:

转换后的table: 

代码里有详细的说明,

还有一些参数我都截图了下面有

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace ConvertToTable
{
class Program
{
static void Main(string[] args)
{
#region 添加一个表
DataTable _dt = new DataTable();
_dt.Columns.Add(new DataColumn("staff_id", typeof(int)) { DefaultValue = 0 }); //员工 id
_dt.Columns.Add(new DataColumn("staff_Name", typeof(string)) { DefaultValue = "1" }); //员工名字
_dt.Columns.Add(new DataColumn("staff_TiCheng", typeof(string)) { DefaultValue = "1" });//员工提成规则
_dt.Columns.Add(new DataColumn("staff_TiChengAmount", typeof(double)) { DefaultValue = 0 }); //提成钱数

_dt.Rows.Add(1, "小李", "零点提成", 60);
_dt.Rows.Add(1, "小李", "订房提成", 70);
_dt.Rows.Add(2, "小张", "零点提成", 500);
_dt.Rows.Add(2, "小张", "订房提成", 60);
_dt.Rows.Add(2, "小张", "订单提成", 800);
_dt.Rows.Add(3, "小王", "零点提成", 30);
_dt.Rows.Add(3, "小王", "订单提成", 900);
#endregion
//输出原始表
Console.WriteLine("原始表:");
DisplayTable(_dt);
//输出行转列以后的表
Console.WriteLine("转换以后的表:");
DisplayTable(ConvertToTable(_dt));
Console.ReadLine();
}

#region 转换表
static DataTable ConvertToTable(DataTable source)
{
DataTable dt = new DataTable();
//前两列是固定的加上
dt.Columns.Add("staff_id");
dt.Columns.Add("staff_Name");
//以staff_TiCheng 字段为筛选条件 列转为行 下面有图
var columns = (from x in source.Rows.Cast<DataRow>() select x[2].ToString()).Distinct();
//把 staff_TiCheng 字段 做为新字段添加进去
foreach (var item in columns) dt.Columns.Add(item).DefaultValue = 0;
// x[1] 是字段 staff_Name 按 staff_Name分组 g 是分组后的信息 g.Key 就是名字 如果不懂就去查一个linq group子句进行分组
var data = from x in source.Rows.Cast<DataRow>()
group x by x[1] into g
select new { Key = g.Key.ToString(), Items = g };
data.ToList().ForEach(x =>
{
//这里用的是一个string 数组 也可以用DataRow根据个人需要用
string[] array = new string[dt.Columns.Count];
//array[1]就是存名字的
array[1] = x.Key;
//从第二列开始遍历
for (int i = 2; i < dt.Columns.Count; i++)
{
// array[0] 就是 staff_id
if (array[0] == null)
array[0] = x.Items.ToList<DataRow>()[0]["staff_id"].ToString();
//array[0] = (from y in x.Items
// where y[2].ToString() == dt.Columns[i].ToString()
// select y[0].ToString()).SingleOrDefault();
//array[i]就是 各种提成
array[i] = (from y in x.Items
where y[2].ToString() == dt.Columns[i].ToString()// y[2] 各种提成名字等于table中列的名字
select y[3].ToString() // y[3] 就是我们要找的 staff_TiChengAmount 各种提成 的钱数
).SingleOrDefault();
}
dt.Rows.Add(array); //添加到table中
});
return dt;
}
/// <summary>
/// 输出表
/// </summary>
/// <param name="dt"></param>
static void DisplayTable(DataTable dt)
{
//输出列的标题
dt.Columns.Cast<DataColumn>().ToList().ForEach(x => Console.Write(x + "\t"));
Console.WriteLine();
//输出每行的信息
dt.Rows.Cast<DataRow>().ToList().ForEach(x =>
{
x.ItemArray.ToList().ForEach(y => Console.Write(y.ToString() + "\t\t"));
Console.WriteLine();
});
}

#endregion
}
}

//以staff_TiCheng 字段为筛选条件  列转为行  下面有图

//   x[1] 是字段 staff_Name

y[2] 各种提成名字等于table中列的名字

 

作者:李鹏
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2012-02-27 18:02  li-peng  阅读(10878)  评论(6编辑  收藏  举报