コード例 #1
0
        public static DynamicBuilder <T> CreateBuilder(IDataRecord dataRecord)
        {
            DynamicBuilder <T> dynamicBuilder = new DynamicBuilder <T>();

            //定义一个名为DynamicCreate的动态方法,返回值typof(T),参数typeof(IDataRecord)
            DynamicMethod method = new DynamicMethod("DynamicCreate", typeof(T), new Type[] { typeof(IDataRecord) }, typeof(T), true);

            ILGenerator generator = method.GetILGenerator();         //创建一个MSIL生成器,为动态方法生成代码

            LocalBuilder result = generator.DeclareLocal(typeof(T)); //声明指定类型的局部变量 可以T t;这么理解

            //The next piece of code instantiates the requested type of object and stores it in the local variable. 可以t=new T();这么理解
            generator.Emit(OpCodes.Newobj, typeof(T).GetConstructor(Type.EmptyTypes));
            generator.Emit(OpCodes.Stloc, result);

            for (int i = 0; i < dataRecord.FieldCount; i++)                               //数据集合,熟悉的for循环 要干什么你懂的
            {
                PropertyInfo propertyInfo = typeof(T).GetProperty(dataRecord.GetName(i)); //根据列名取属性  原则上属性和列是一一对应的关系
                Label        endIfLabel   = generator.DefineLabel();

                if (propertyInfo != null && propertyInfo.GetSetMethod() != null)//实体存在该属性 且该属性有SetMethod方法
                {
                    /*The code then loops through the fields in the data reader, finding matching properties on the type passed in.
                     * When a match is found, the code checks to see if the value from the data reader is null.
                     */
                    generator.Emit(OpCodes.Ldarg_0);
                    generator.Emit(OpCodes.Ldc_I4, i);
                    generator.Emit(OpCodes.Callvirt, isDBNullMethod);//就知道这里要调用IsDBNull方法 如果IsDBNull==true contine
                    generator.Emit(OpCodes.Brtrue, endIfLabel);

                    /*If the value in the data reader is not null, the code sets the value on the object.*/
                    generator.Emit(OpCodes.Ldloc, result);
                    generator.Emit(OpCodes.Ldarg_0);
                    generator.Emit(OpCodes.Ldc_I4, i);
                    generator.Emit(OpCodes.Callvirt, getValueMethod);              //调用get_Item方法
                    generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(i));
                    generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod()); //给该属性设置对应值

                    generator.MarkLabel(endIfLabel);
                }
            }

            /*The last part of the code returns the value of the local variable*/
            generator.Emit(OpCodes.Ldloc, result);
            generator.Emit(OpCodes.Ret);//方法结束,返回

            //完成动态方法的创建,并且创建执行该动态方法的委托,赋值到全局变量handler,handler在Build方法里Invoke
            dynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load));

            return(dynamicBuilder);
        }
コード例 #2
0
ファイル: BaseDAO.cs プロジェクト: zjchenxk/SYLS
        /// <summary>
        /// 执行存储过程读取数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="strProcedure"></param>
        /// <param name="strErrText"></param>
        /// <returns></returns>
        protected List <T> LoadData <T>(string strProcedure, out string strErrText)
        {
            List <T>      models = new List <T>();
            SqlDataReader dr     = null;

            try
            {
                SqlCommand command = new SqlCommand();
                command.Connection     = m_conn;
                command.CommandTimeout = 7200;
                command.CommandText    = strProcedure;
                command.CommandType    = CommandType.StoredProcedure;

                m_strInfoMessage = string.Empty;

                dr = command.ExecuteReader();

                DynamicBuilder <T> builder = DynamicBuilder <T> .CreateBuilder(dr);

                while (dr.Read())
                {
                    T model = default(T);
                    model = builder.Build(dr);
                    models.Add(model);
                }

                //用于获取存储过程RaiseError命令发出的错误消息。
                //如果存储过程中执行了RaiseError命令,则调用NextResult时就会引发异常
                dr.NextResult();

                dr.Close();
                dr.Dispose();

                strErrText = string.Empty;
                return(models);
            }
            catch (Exception e)
            {
                if (dr != null)
                {
                    dr.Close();
                    dr.Dispose();
                }

                strErrText = e.Message;
                return(null);
            }
        }