LinQ實現DataTable不定行轉列 行列轉換,有圖
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="LinqDemo2.aspx.cs" Inherits="LinqDemo2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>LinQ實現DataTable不定行轉列</title>
</head>
<body>
<form id="form1" runat="server">
<div>
原始表:<br />
<asp:GridView ID="GridView1" runat="server" Width="300px">
</asp:GridView>
<br />
轉換以後的表:<br />
<asp:GridView ID="GridView2" runat="server" Width="300px">
</asp:GridView>
</div>
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class LinqDemo2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
#region 新增一個表
DataTable _dt = new DataTable();
_dt.Columns.Add(new DataColumn("ID", typeof(int)) { DefaultValue = 0 }); //員工 id
_dt.Columns.Add(new DataColumn("Name", typeof(string)) { DefaultValue = "1" }); //員工名字
_dt.Columns.Add(new DataColumn("Item", typeof(string)) { DefaultValue = "1" });//員工提成規則
_dt.Columns.Add(new DataColumn("ItemAmount", 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
//輸出原始表
GridView1.DataSource = _dt;
GridView1.DataBind();
//輸出行轉列以後的表
GridView2.DataSource = ConvertToTable(_dt);
GridView2.DataBind();
}
#region 轉換表
static DataTable ConvertToTable(DataTable source)
{
DataTable dt = new DataTable();
//前兩列是固定的加上
dt.Columns.Add("ID");
dt.Columns.Add("Name");
//以Item 欄位為篩選條件 列轉為行 下面有圖
var columns = (from x in source.Rows.Cast<DataRow>() select x[2].ToString()).Distinct();
//把 Item 欄位 做為新欄位新增進去
foreach (var item in columns) dt.Columns.Add(item).DefaultValue = 0;
// x[1] 是欄位 Name 按 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] 就是 ID
if (array[0] == null)
array[0] = x.Items.ToList<DataRow>()[0]["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] 就是我們要找的 ItemAmount 各種提成 的錢數
).SingleOrDefault();
}
dt.Rows.Add(array); //新增到table中
});
return dt;
}
#endregion
}