У меня есть проект на основе ASP.NET MVC 5, написанный на c #.Я создал помощник Razor, который называется @Html.DisplayTableFor(x => x.Records)
, где Records
реализует IEnumerable
.
. Метод расширения DisplayTableFor
создаст таблицу HTML, где каждый record
в коллекции Records
представляет строку (<tr>...</tr>
) в таблице HTML.Это прекрасно работает для меня сейчас, когда я просто хочу записать данные в таблицу 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
![enter image description here](https://i.stack.imgur.com/ECeiA.png)
Следуйте - мой первый подход к созданию сводной таблицы.Сначала я бы осмотрел общий тип коллекции.Если универсальный тип реализует интерфейс 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
?