我有一个使用c#编写的基于ASP.NET MVC 5的项目。我创建了一个名为@Html.DisplayTableFor(x => x.Records)
的Razor帮助器,其中Records
实现了IEnumerable
。
DisplayTableFor
扩展方法将创建一个HTML表,其中record
集合中的每个Records
代表HTML表中的一行(<tr>...</tr>
)。当我只想将数据转储到HTML表中时,它对我来说非常有用。但是,我想进一步扩展它,以便它可以接受分组列表并呈现它,并使摘要表看起来不仅是原始数据转储。
例如,如果我有以下行数据
Name Salary Department
John Doe 100000 IT
Jane Doe 75000 Sales
Jay T 50000 Sales
Jack S 60000 Sales
Mike S 65000 IT
Dave B 70000 IT
B Smith 80000 IT
假设我要按Department
然后按Name
对记录进行分组。我希望DisplayTableFor
方法在HTML表中生成类似此输出的内容
跟随是我生成汇总表的第一种方法。首先,我将检查集合的通用类型。如果泛型类型实现了IGrouping
接口,那么我将知道此集合是分组的,应将其呈现为摘要表,否则将数据呈现为数据转储格式。
这是代表每个原始行的模型。
public class Record
{
public string Name { get; set; }
public string Department { get; set; }
public double Salary { get; set; }
}
public class RecordsKey
{
public string Name { get; set; }
public string Department { get; set; }
}
这是我创建摸索的收藏集的方式。
var records = new List<Record>(){.. some records ...}
var grouped = records.GroupBy(x => new RecordsKey
{
Department = x.Department,
Name = x.Name
}).ToList();
在我的DisplayTableFor
扩展方法中,我执行以下代码来查找通用类型(即ModelMetadata
)的IGouping<RecordsKey, Records>
Type type = TableHelpers.GetCollectionType(propertyMetadata.Model as IEnumerable);
if (type == null)
{
throw new ArgumentException("Unable to find the generic type");
}
ModelMetadata typeMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, type);
var columns = new Dictionary<string, TableDataColumn>();
foreach (ModelMetadata propertyMetadata in propertyMetadatas)
{
// TODO... Execution steps
// IF propertyMetadata.ModelType is assignable from IGrouping<>
// 1) Find the generic type of the "IGrouping.Key" and foreach property on the Type create new TableDataColumn()
// 2) Find the generic type of the "IGrouping.Value" and foreach property on the Type create a new TableDataColumn()
// ELSE
// columns.Add(new TableDataColumn(propertyMetadata));
// ENDIF
}
但是,我无法将上面注释中的TODO步骤转换为有效的C#代码。
问题,如何检查类型是否实现IGrouping
?另外,如何获得ModelMetadata
和IGrouping.Key
中的IGrouping.Value
?