/// <summary> /// 動態填寫實體類的值 /// </summary> /// <typeparam name="T"></typeparam> public class DynamicEntityBuilder<T> { private static readonly MethodInfo getValueMethod = typeof(IDataRecord).GetMethod("get_Item", new Type[] { typeof(int) }); private static readonly MethodInfo isDBNullMethod = typeof(IDataRecord).GetMethod("IsDBNull", new Type[] { typeof(int) }); private delegate T Load(IDataRecord dataRecord); private Load handler; private DynamicEntityBuilder() { } public T Build(IDataRecord dataRecord) { return handler(dataRecord); } public static DynamicEntityBuilder<T> CreateBuilder(IDataRecord dataRecord) { DynamicEntityBuilder<T> dynamicBuilder = new DynamicEntityBuilder<T>(); DynamicMethod method = new DynamicMethod("DynamicCreate", typeof(T), new Type[] { typeof(IDataRecord) }, typeof(T), true); ILGenerator generator = method.GetILGenerator(); LocalBuilder result = generator.DeclareLocal(typeof(T)); generator.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes)); generator.Emit(OpCodes.Stloc, result); for (int i = 0; i < dataRecord.FieldCount; i++) { PropertyInfo propertyInfo = typeof(T).GetProperty(dataRecord.GetName(i)); Label endIfLabel = generator.DefineLabel(); if (propertyInfo != null && propertyInfo.GetSetMethod() != null) { generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Callvirt, isDBNullMethod); generator.Emit(OpCodes.Brtrue, endIfLabel); generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Callvirt, getValueMethod); generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(i)); generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod()); generator.MarkLabel(endIfLabel); } } generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ret); dynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load)); return dynamicBuilder; } }
使用
public ERole Select(int roleID) { ERole entity = new ERole(); string sql = string.Format("select * from Role with(nolock) where roleid = {0}",roleID); DbCommand cmd = Db.EsfCrmReader.GetSqlStringCommand(sql); using (IDataReader dataReader = Db.EsfCrmReader.ExecuteReader(cmd)) { if (dataReader.Read()) { entity = DynamicEntityBuilder<ERole>.CreateBuilder(dataReader).Build(dataReader); } } return entity; }