在处理大量数据或希望以逻辑分组/聚合的方式按列显示数据时,本文介绍的扩展方法将为提供帮助。本文旨在简化在表现层拥有IEnumerable
为了在UI中显示数据,还需要一个网格控件。因此,创建了一个简单的自定义网格控件,它从IEnumerable
在发表的一文后,收到了许多读者的电子邮件,他们希望在ASP.NET MVC中也能进行数据透视。因此,决定撰写一篇关于在ASP.NET MVC中进行数据透视的文章。在之前的文章中,提供了许多不同形式的数据透视样本。为了保持文章的简洁性,并且由于时间有限,本文没有提供很多样本。但这些样本可以很容易地按照之前文章中提供的方式推导出来。未来可能会在本文中提供许多不同的数据透视选项。现在,请先看看带有简单网格/报告控件的基本数据透视。
要使用代码,只需添加对ReportControl程序集的引用。然后,可以直接在视图中使用代码,如下所示:
@Model.ReportWithPivot(
"",
"ShopName",
"SellingPrice",
AggregateFunction.Sum,
"ItemType",
"ItemName")
请注意,模型应该是IEnumerable或派生自IEnumerable。
要了解与数据透视相关的内容的工作原理,请查看之前的文章:。此外,ReportWithPivot是一个扩展IEnumerable对象的方法,它接受RowField、DataField、Aggregate Function和ColumnFields作为参数,并返回一个根据指定参数透视数据的HTML表格。
public static HtmlString ReportWithPivot(
this IEnumerable source,
string cssClass,
string rowField,
string dataField, AggregateFunction aggregate,
params string[] columnFields)
where T : class
{
DataTable dt = source.ToDataTable();
return dt.ReportWithPivot(cssClass, rowField, dataField, aggregate, columnFields);
}
为了简化事情,这个方法的工作可以按照以下步骤进行解释:
一个名为ReportWithPivot的扩展方法被调用,它接受透视参数。
这个方法首先将IEnumerable源转换为DataTable,然后调用另一个接受DataTable作为参数的ReportWithPivot方法。为了透视源,首先将数据转换为DataTable,因为通过将其分割成不同的部分来动态操作DataTable是很容易的。
现在,它按照之前文章中解释的同样方式透视DataTable中的数据。在一个新的DataTable中得到透视数据。
透视表的表头由ReportHelper类中的PivotHeader(this Table table, string separator, int pivotLevel)函数设置。它首先添加表中的表头行数,并根据透视级别和内容应用数据。然后,它检查并合并重复的单元格数据。
public static void PivotHeader(
this Table table,
string separator,
int pivotLevel)
{
TableRow row = table.Rows[0];
if (row.TableSection == TableRowSection.TableHeader)
{
TableRow r = new TableRow();
var headers = row.Cells.Cast().Select(x => x.Text);
for (int i = 0; i < pivotLevel; i++)
{
r = new TableRow();
r.TableSection = TableRowSection.TableHeader;
foreach (var x in headers)
{
string headerText = GetNthText(x, i, separator);
if (r.Cells.Count > 0 && r.Cells[r.Cells.Count - 1].Text == headerText)
r.Cells[r.Cells.Count - 1].ColumnSpan++;
else
r.Cells.Add(new TableHeaderCell { Text = headerText, ColumnSpan = 1 });
}
table.Rows.AddAt(i, r);
}
}
table.Rows.Remove(row);
}
下面的图片是透视和原始报告的屏幕截图:
本文还提供了一个示例,说明如何创建一个简单的Report/Grid扩展方法来从集合渲染HTML。对于初学者来说,其中的代码也可以作为如何使用反射来读取属性并从中获取值的示例。下面的代码演示了这一点:
public static DataTable ToDataTable(
this IEnumerable data)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
PropertyInfo[] properties = typeof(T).GetProperties();
DataTable table = new DataTable();
foreach (PropertyInfo prop in properties)
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
foreach (T item in data)
{
DataRow row = table.NewRow();
foreach (PropertyInfo prop in properties)
row[prop.Name] = prop.GetValue(item, null) ?? DBNull.Value;
table.Rows.Add(row);
}
return table;
}
目前,只添加了一个基本的透视报告样本。请继续关注本文,以查看更多关于透视的功能。