Я добавил бы следующие новые поля к вышеупомянутой таблице:
thread_id: идентификатор для всех комментариев, присоединенных к конкретному объекту
дата: дата комментария (позволяет выбирать комментарии в порядке)
разряд: разряд комментария (позволяет выбирать порядок комментария путем рейтинга)
Используя эти поля Вы будете в состоянии:
, К сожалению, если Вы хотите сохранить свой DB запросов близко к стандарту SQL, необходимо будет воссоздать дерево в памяти. Некоторый DBS предлагает специальные запросы для иерархических данных (f.e. Oracle)
./alex
Любые свойства, являющиеся типами значений ( int
и т. Д.), Нуждаются в упаковке; или вам нужно будет использовать другую перегрузку Append
.
Также:
StringBuilder.Append
- это свободный API; вам нужно либо вставить значение, либо повторно использовать его: (хотя лично я бы вернул строку
, но "meh")
Примерно так:
DynamicAccessor<T> dynAccessor = new DynamicAccessor<T>();
MethodInfo AppendMethod = typeof(StringBuilder).GetMethod("Append", new[] { typeof(Object) }); //Append method of Stringbuilder
var method = new DynamicMethod("ClassWriter", typeof(StringBuilder), new[] { typeof(T) }, typeof(T), true);
var generator = method.GetILGenerator();
generator.Emit(OpCodes.Newobj, typeof(StringBuilder).GetConstructor(Type.EmptyTypes)); //make our string builder
//iterate through all the instance of T's props and sb.Append their values.
PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var info in props)
{
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Callvirt, info.GetGetMethod()); //call the Getter
if (info.PropertyType.IsValueType)
{
generator.Emit(OpCodes.Box, info.PropertyType);
}
generator.Emit(OpCodes.Callvirt, AppendMethod); //Call Append
}
generator.Emit(OpCodes.Ret); //return pointer to sb
Это создает эквивалент:
StringBuilder ClassWriter(T obj) {
return new StringBuilder.Append((object)obj.Foo).Append((object)obj.Bar)
.Append((object)obj.Blip).Append((object)obj.Blap);
}