エンティティ・クラスの値の動的入力

6963 ワード

/// <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;

        }