在我的控制器中,我回傳由我的模型定義的資料庫查詢結果(物件串列)。我在視圖中顯示這個。例如:
| 道具1 | 道具2 | 道具3 | 道具4 | 道具5 |
|---|---|---|---|---|
| AAA | 1123 | 400 | 35% | 600 美元 |
| BBB | 3444 | 23 | 45% | 235 美元 |
| CCC | 5000 | 55 | 15% | 555 美元 |
| DDD | 2500 | 264 | 70% | 243 美元 |
我想將此結果轉換為如下所示:
| 道具1 | AAA | BBB | CCC | DDD |
|---|---|---|---|---|
| 道具2 | 1123 | 3444 | 5000 | 2500 |
| 道具3 | 400 | 23 | 55 | 264 |
| 道具4 | 35% | 45% | 15% | 70% |
| 道具5 | 600 美元 | 235 美元 | 555 美元 | 243 美元 |
實作這一目標的最佳方法是什么?我最初以 SQL 查詢為中心,并有一個代表底部結果的模型,但是由于我經常更改和請求添加從其他列計算的新欄位等,因此變得難以管理。
uj5u.com熱心網友回復:
請參閱下面的示例實作擴展方法,該方法使用反射來旋轉IEnumerable<T>.
示例用法 Pivot()
// Test Type
public record MyObj(string Prop1, int Prop2, int Prop3);
// test data
var list = new List<MyObj> {
new MyObj("AAA", 1123, 400),
new MyObj("BBB", 2123, 500),
new MyObj("CCC", 3123, 600)
};
Console.Write(list.Pivot());

示例用法 Pivot() w/ ColumnSelector
示例 1
Console.Write(list.Pivot( pivotOn: (f)=>f.Prop1));

示例 2
Console.Write(list.Pivot( pivotOn: (f)=>f.Prop2));

執行
public static class PivotExtension
{
public static IEnumerable<ExpandoObject> Pivot<T>(this IEnumerable<T> objs)
{
var objArray = objs.ToArray();
var properties = typeof(T).GetProperties();
foreach (var property in properties)
{
var obj = new ExpandoObject();
var objDic = (IDictionary<string, object>)obj;
objDic.Add("Name", property.Name);
for (int i = 1; i < objs.Count(); i )
objDic.Add($"Row_{i.ToString()}", property.GetValue(objArray[i]));
yield return obj;
}
}
public static IEnumerable<ExpandoObject> Pivot<T, TValue>(this IEnumerable<T> objs, Expression<Func<T, TValue>> pivotOn)
{
var objArray = objs.ToList();
var properties = typeof(T).GetProperties();
var pivotProperty = pivotOn.GetProperty();
//header
var cnt = 1;
var pivotHeader = new Dictionary<int, string>{{0, pivotProperty.Name}};
objArray.ForEach(r=> pivotHeader.Add( cnt , pivotProperty.GetValue(r).ToString()));
//rotate
foreach (var property in properties.Where(r=> !pivotHeader.ContainsValue(r.Name)))
{
var obj = new ExpandoObject();
var objDic = (IDictionary<string, object>)obj;
objDic.Add(pivotHeader[0], property.Name);
for (int i = 0; i < objs.Count(); i )
objDic.Add($"{pivotHeader[i 1]}", property.GetValue(objArray[i]));
yield return obj;
}
}
public static PropertyInfo GetProperty<T, TValue>(this Expression<Func<T, TValue>> expression)
{
return GetProperty(expression.Body);
}
private static PropertyInfo GetProperty(Expression body)
{
MemberExpression memberExpression;
switch (body.NodeType)
{
case ExpressionType.Convert:
memberExpression = (MemberExpression)((UnaryExpression)body).Operand;
break;
case ExpressionType.MemberAccess:
memberExpression = (MemberExpression)body;
break;
default:
throw new ArgumentOutOfRangeException();
}
return (PropertyInfo)memberExpression.Member;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/510623.html
下一篇:不包括周末的列值的LINQ總和
