Благодаря @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)
Ну, в конце концов, он выглядит очень похоже на глобальные переменные, но я думаю, что это решение соответствует моим потребностям. Что самое важное, мне удалось выбраться из перекрестных ссылок.
Это не будет фактической утечкой, но она могла подчеркивать вещи излишне...
Сколько строк Вы работаете? Обратите внимание, что отражение является болью, и что каждый вызов к вещам как 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;
}