Преобразовать DataTable в универсальный Список?

Благодаря @coleifer я решил создать еще один класс для обработки базы данных:

class DbHandler:
    database = SqliteDatabase(None)

    @staticmethod
    def start(dbSrc):
        DbHandler.database.init(
            dbSrc + '\\res\\SIMail.db',
            pragmas={'foreign_keys': 1})
        DbHandler.database.connect()
        DbHandler.database.create_tables([RouterSettings, BalanceEntry],
                                         safe=True)

Ну, в конце концов, он выглядит очень похоже на глобальные переменные, но я думаю, что это решение соответствует моим потребностям. Что самое важное, мне удалось выбраться из перекрестных ссылок.

6
задан TimLeung 3 May 2012 в 23:11
поделиться

1 ответ

Это не будет фактической утечкой, но она могла подчеркивать вещи излишне...

Сколько строк Вы работаете? Обратите внимание, что отражение является болью, и что каждый вызов к вещам как GetCustomAttributes может возвратить новый массив (таким образом, Вы хотите сделать это однажды, не однажды per-property-per-row).

Лично, я предварительно создал бы работу, как которая я намереваюсь сделать... что-то ниже.

Обратите внимание, что, если бы я делал это партии, я или переключился бы на HyperDescriptor, или если.NET 3.5 была опцией, возможно, скомпилированное Выражение. С тех пор DataTable не со строгим контролем типов, HyperDescriptor был бы логический следующий шаг (для производительности) после ниже...

sealed class Tuple<T1, T2>
{
    public Tuple() {}
    public Tuple(T1 value1, T2 value2) {Value1 = value1; Value2 = value2;}
    public T1 Value1 {get;set;}
    public T2 Value2 {get;set;}
}
public static List<T> Convert<T>(DataTable table)
    where T : class, new()
{
    List<Tuple<DataColumn, PropertyInfo>> map =
        new List<Tuple<DataColumn,PropertyInfo>>();

    foreach(PropertyInfo pi in typeof(T).GetProperties())
    {
        ColumnAttribute col = (ColumnAttribute)
            Attribute.GetCustomAttribute(pi, typeof(ColumnAttribute));
        if(col == null) continue;
        if(table.Columns.Contains(col.FieldName))
        {
            map.Add(new Tuple<DataColumn,PropertyInfo>(
                table.Columns[col.FieldName], pi));
        }
    }

    List<T> list = new List<T>(table.Rows.Count);
    foreach(DataRow row in table.Rows)
    {
        if(row == null)
        {
            list.Add(null);
            continue;
        }
        T item = new T();
        foreach(Tuple<DataColumn,PropertyInfo> pair in map) {
            object value = row[pair.Value1];
            if(value is DBNull) value = null;
            pair.Value2.SetValue(item, value, null);
        }
        list.Add(item);
    }
    return list;        
}
9
ответ дан 10 December 2019 в 02:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: