У меня есть этот универсальный вспомогательный метод.Я передаю список заданного типа (при условии, что у вас есть вспомогательный класс), и он генерирует таблицу данных со свойствами в качестве заголовков столбцов и элементов списка в качестве данных.
Так же, как в стандартном MVC, если вы неопределив атрибут DisplayName, он будет возвращаться к имени свойства, поэтому вы должны включать DisplayName только в том случае, если оно отличается от имени свойства.
public DataTable BuildDataTable<T>(IList<T> data)
{
//Get properties
PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
//.Where(p => !p.GetGetMethod().IsVirtual && !p.GetGetMethod().IsFinal).ToArray(); //Hides virtual properties
//Get column headers
bool isDisplayNameAttributeDefined = false;
string[] headers = new string[Props.Length];
int colCount = 0;
foreach (PropertyInfo prop in Props)
{
isDisplayNameAttributeDefined = Attribute.IsDefined(prop, typeof(DisplayNameAttribute));
if (isDisplayNameAttributeDefined)
{
DisplayNameAttribute dna = (DisplayNameAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayNameAttribute));
if (dna != null)
headers[colCount] = dna.DisplayName;
}
else
headers[colCount] = prop.Name;
colCount++;
isDisplayNameAttributeDefined = false;
}
DataTable dataTable = new DataTable(typeof(T).Name);
//Add column headers to datatable
foreach (var header in headers)
dataTable.Columns.Add(header);
dataTable.Rows.Add(headers);
//Add datalist to datatable
foreach (T item in data)
{
object[] values = new object[Props.Length];
for (int col = 0; col < Props.Length; col++)
values[col] = Props[col].GetValue(item, null);
dataTable.Rows.Add(values);
}
return dataTable;
}
Если есть более эффективный / безопасный способ сделать это,Я бы оценил любой отзыв.Закомментированное предложение // Where будет отфильтровывать виртуальные свойства.Полезно, если вы используете классы моделей напрямую, так как EF вводит свойства «Навигация» как виртуальные.Однако он также отфильтрует любые ваши собственные виртуальные свойства, если вы решите расширить такие классы.По этой причине я предпочитаю создать ViewModel и украсить его только необходимыми свойствами и отображаемыми атрибутами по мере необходимости, а затем составить их список.
Надеюсь, это поможет.