C# 行列互转 List<T>、DataTable和匿名对象 行转列
在将列转换为行之后,您可能希望获得List或dynamic[],而不是获得DataTable。在这篇文章中,我们将做同样的事情,但是使用c#的数组和数据表,使用LINQ或Lambda表达式的力量。您可以使用相同的扩展方法来获取如下所示的行转列的 DataTable。为此,我更新了扩展方法以获得动态对象。C# 将Datatable行转列成Datatable。您可以为扩展方法创建一个静态类并将其放在那
用LINQ把列转换成行
在这篇文章中,我们将做同样的事情,但是使用c#的数组和数据表,使用LINQ或Lambda表达式的力量
C# 数组集合或者List<T> 行转列到 DataTable
这里是C#对象
var data = new[] {
new { Product = "Product 1", Year = 2009, Sales = 1212 },
new { Product = "Product 2", Year = 2009, Sales = 522 },
new { Product = "Product 1", Year = 2010, Sales = 1337 },
new { Product = "Product 2", Year = 2011, Sales = 711 },
new { Product = "Product 2", Year = 2012, Sales = 2245 },
new { Product = "Product 3", Year = 2012, Sales = 1000 }
};
var pivotTable1 = data.ToPivotTable(item => item.Year, item => item.Product, items => items.Any() ? items.Sum(x => x.Sales) : 0);
jsonStr = JsonConvert.SerializeObject(pivotTable);
//行转列
下面是我们定义的扩展方法
public static DataTable ToPivotTable<T, TColumn, TRow, TData>(
this IEnumerable<T> source,
Func<T, TColumn> columnSelector,
Expression<Func<T, TRow>> rowSelector,
Func<IEnumerable<T>, TData> dataSelector)
{
DataTable table = new DataTable();
var rowName = ((MemberExpression)rowSelector.Body).Member.Name;
table.Columns.Add(new DataColumn(rowName));
var columns = source.Select(columnSelector).Distinct();
foreach (var column in columns)
table.Columns.Add(new DataColumn(column.ToString()));
var rows = source.GroupBy(rowSelector.Compile())
.Select(rowGroup => new
{
Key = rowGroup.Key,
Values = columns.GroupJoin(
rowGroup,
c => c,
r => columnSelector(r),
(c, columnGroup) => dataSelector(columnGroup))
});
foreach (var row in rows)
{
var dataRow = table.NewRow();
var items = row.Values.Cast<object>().ToList();
items.Insert(0, row.Key);
dataRow.ItemArray = items.ToArray();
table.Rows.Add(dataRow);
}
return table;
}
您可以为扩展方法创建一个静态类并将其放在那里。
要将年份值转换为列并获取数据透视表:
C# 将List<T>集合行转列到匿名对象集合
在将列转换为行之后,您可能希望获得List<dynamic>或dynamic[],而不是获得DataTable。它在ASP中很方便。NET Web API返回JSON响应。
为此,我更新了扩展方法以获得动态对象。使用以下扩展方法:
吗?
public static List<dynamic> ToPivotArray<T, TColumn, TRow, TData>(
this IEnumerable<T> source,
Func<T, TColumn> columnSelector,
Expression<Func<T, TRow>> rowSelector,
Func<IEnumerable<T>, TData> dataSelector)
{
var arr = new List<object>();
var cols = new List<string>();
String rowName = ((MemberExpression)rowSelector.Body).Member.Name;
var columns = source.Select(columnSelector).Distinct();
cols =(new []{ rowName}).Concat(columns.Select(x=>x.ToString())).ToList();
var rows = source.GroupBy(rowSelector.Compile())
.Select(rowGroup => new
{
Key = rowGroup.Key,
Values = columns.GroupJoin(
rowGroup,
c => c,
r => columnSelector(r),
(c, columnGroup) => dataSelector(columnGroup))
}).ToArray();
foreach (var row in rows)
{
var items = row.Values.Cast<object>().ToList();
items.Insert(0, row.Key);
var obj = GetAnonymousObject(cols, items);
arr.Add(obj);
}
return arr.List();
}
private static dynamic GetAnonymousObject(IEnumerable<string> columns, IEnumerable<object> values)
{
IDictionary<string, object> eo = new ExpandoObject() as IDictionary<string, object>;
int i;
for (i = 0; i < columns.Count(); i++)
{
eo.Add(columns.ElementAt<string>(i), values.ElementAt<object>(i));
}
return eo;
}
ExpandoObject用于创建动态对象
现在,要将行转换为列并获得动态数组
C# 将Datatable行转列成Datatable
让我们有一个带有相同数据的数据表
DataTable myDataTable = new DataTable();
myDataTable.Columns.AddRange(new DataColumn[3] { new DataColumn("Product"),
new DataColumn("Year", typeof(int)), new DataColumn("Sales", typeof(int)) });
myDataTable.Rows.Add("Product 1", 2009, 1212);
myDataTable.Rows.Add("Product 2", 2009, 522);
myDataTable.Rows.Add("Product 1", 2010, 1337);
myDataTable.Rows.Add("Product 2", 2011, 711);
myDataTable.Rows.Add("Product 2", 2012, 2245);
myDataTable.Rows.Add("Product 3", 2012, 1000);
您可以使用相同的扩展方法来获取如下所示的行转列的 DataTable。
DataTable to List<dynamic>:
如果你需要将DataTable转换为List of dynamic object,那么使用以下扩展方法:
public static List<dynamic> ToDynamicList(this DataTable dt)
{
var list = new List<dynamic>();
foreach (DataRow row in dt.Rows)
{
dynamic dyn = new ExpandoObject();
list.Add(dyn);
foreach (DataColumn column in dt.Columns)
{
var dic = (IDictionary<string, object>)dyn;
dic[column.ColumnName] = row[column];
}
}
return list;
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)