c # - создать таблицу данных из класса (не список экземпляров) - PullRequest
4 голосов
/ 09 июня 2011

Этот вопрос касается обобщенных типов и типов, а также таблиц данных.

Следующий фрагмент находится вокруг сети здесь и там и создает таблицу данных на основе универсального типа:

public static DataTable ListToDataTable<T>(List<T> list)
{
    DataTable dt = new DataTable();

    foreach (PropertyInfo info in typeof(T).GetProperties())
    {
        dt.Columns.Add(new DataColumn(info.Name, info.PropertyType));
    }
    foreach (T t in list)
    {
        DataRow row = dt.NewRow();
        foreach (PropertyInfo info in typeof(T).GetProperties())
        {
            row[info.Name] = info.GetValue(t, null);
        }
        dt.Rows.Add(row);
    }
    return dt;
}

Я использую отличную библиотеку FileHelpers для импорта пакетов записей в SQL Server. Чтобы использовать SqlBulkCopy, мне нужен набор данных со столбцами данного типа. Filehelpers может читать в файле .cs во время выполнения и создавать свой тип на основе этого. например:

System.Type userType = null;
userType = ClassBuilder.ClassFromSourceFile("myclassfile.cs");

Я бы хотел изменить описанный выше метод, чтобы он просто создавал столбцы для меня при передаче типа (например, 'userType'). то есть сигнатура метода будет выглядеть примерно так:

public static DataTable TypeToDataTable<T>(<T> myType)

и вернет пустой набор данных со столбцами, готовый к добавлению в него строк userType.

Я пробовал разные методы - есть идеи?

Ответы [ 2 ]

10 голосов
/ 09 июня 2011

Это на самом деле довольно просто, когда вы понимаете, что вам не нужно (или даже можете) использовать дженерики в этом случае:

public static DataTable CreateEmptyDataTable(Type myType)
{
    DataTable dt = new DataTable();

    foreach (PropertyInfo info in myType.GetProperties())
    {
        dt.Columns.Add(new DataColumn(info.Name, info.PropertyType));
    }

    return dt;
}

Вы бы назвали это так:

System.Type userType = null;
userType = ClassBuilder.ClassFromSourceFile("myclassfile.cs");
DataTable emptyDataTable = CreateEmptyDataTable(userType);
2 голосов
/ 03 апреля 2017

Недавно мне нужно было именно это, и я нашел это здесь на SO.Я объединил предпосылку в вопросе с ответом и решил поделиться кодом, поскольку оба они неполные:

private DataTable CreateDataTableFromObjects<T>(List<T> items, string name = null)
{
    var myType = typeof(T);
    if (name == null)
    {
        name = myType.Name;
    }
    DataTable dt = new DataTable(name);
    foreach (PropertyInfo info in myType.GetProperties())
    {
        dt.Columns.Add(new DataColumn(info.Name, info.PropertyType));
    }
    foreach (var item in items)
    {
        DataRow dr = dt.NewRow();
        foreach (PropertyInfo info in myType.GetProperties())
        {
            dr[info.Name] = info.GetValue(item);
        }
        dt.Rows.Add(dr);
    }
    return dt;
}
...