Использовать Reflection.Emit для создания общего метода для заполнения ExpandoObject.
ИЛИ использовать выражения (возможно, это возможно только в .NET 4).
Ни один из этих подходов не использует отражение при вызове, только при настройке делегата (который, очевидно, необходимо кэшировать).
Вот какой код Reflection.Emit для заполнения словаря (я думаю, что ExpandoObject не за горами );
static T CreateDelegate<T>(this DynamicMethod dm) where T : class
{
return dm.CreateDelegate(typeof(T)) as T;
}
static Dictionary<Type, Func<object, Dictionary<string, object>>> cache =
new Dictionary<Type, Func<object, Dictionary<string, object>>>();
static Dictionary<string, object> GetProperties(object o)
{
var t = o.GetType();
Func<object, Dictionary<string, object>> getter;
if (!cache.TryGetValue(t, out getter))
{
var rettype = typeof(Dictionary<string, object>);
var dm = new DynamicMethod(t.Name + ":GetProperties", rettype,
new Type[] { typeof(object) }, t);
var ilgen = dm.GetILGenerator();
var instance = ilgen.DeclareLocal(t);
var dict = ilgen.DeclareLocal(rettype);
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Castclass, t);
ilgen.Emit(OpCodes.Stloc, instance);
ilgen.Emit(OpCodes.Newobj, rettype.GetConstructor(Type.EmptyTypes));
ilgen.Emit(OpCodes.Stloc, dict);
var add = rettype.GetMethod("Add");
foreach (var prop in t.GetProperties(
BindingFlags.Instance |
BindingFlags.Public))
{
ilgen.Emit(OpCodes.Ldloc, dict);
ilgen.Emit(OpCodes.Ldstr, prop.Name);
ilgen.Emit(OpCodes.Ldloc, instance);
ilgen.Emit(OpCodes.Ldfld, prop);
ilgen.Emit(OpCodes.Castclass, typeof(object));
ilgen.Emit(OpCodes.Callvirt, add);
}
ilgen.Emit(OpCodes.Ldloc, dict);
ilgen.Emit(OpCodes.Ret);
cache[t] = getter =
dm.CreateDelegate<Func<object, Dictionary<string, object>>>();
}
return getter(o);
}
Yes, SERIAL is the equivalent function.
CREATE TABLE foo (
id SERIAL,
bar varchar);
INSERT INTO foo (bar) values ('blah');
INSERT INTO foo (bar) values ('blah');
SELECT * FROM foo;
1,blah
2,blah
SERIAL is just a create table time macro around sequences. You can not alter SERIAL onto an existing column.