예제 #1
0
        public static DynamicBuilder <T> CreateBuilder(IDataRecord dr)
        {
            DynamicBuilder <T> dynamicBuilder = new DynamicBuilder <T>();

            dynamicBuilder.handler = (Load)MyStagingUtils.CreateDynamicDelegate(typeof(T), dr, typeof(Load));
            return(dynamicBuilder);
        }
예제 #2
0
        /// <summary>
        ///  创建动态执行代码
        /// </summary>
        /// <param name="dataRecord"></param>
        /// <returns></returns>
        public static DynamicBuilder <T> CreateBuilder(IDataRecord dataRecord)
        {
            DynamicBuilder <T> dynamicBuilder = new DynamicBuilder <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);

            PropertyInfo[] pis = typeof(T).GetProperties();
            IDictionary <string, PropertyInfo> drNameList = new Dictionary <string, PropertyInfo>();

            for (int i = 0; i < pis.Length; i++)
            {
                PropertyInfo pi = pis[i];
                drNameList[pi.Name.ToLower()] = pi;
            }
            for (int i = 0; i < dataRecord.FieldCount; i++)
            {
                string fieldName = dataRecord.GetName(i).ToLower();
                if (drNameList.ContainsKey(fieldName) == false)
                {
                    continue;
                }

                PropertyInfo propertyInfo = drNameList[fieldName];
                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);

                    Type memberType         = propertyInfo.PropertyType;
                    Type nullUnderlyingType = Nullable.GetUnderlyingType(memberType);
                    Type unboxType          = nullUnderlyingType != null ? nullUnderlyingType : memberType;
                    bool isEnum             = unboxType.GetTypeInfo().IsEnum;
                    if (unboxType == typeof(byte[]) || unboxType == typeof(string))
                    {
                        generator.Emit(OpCodes.Castclass, memberType);
                    }
                    else if (isEnum)
                    {
                        generator.Emit(OpCodes.Unbox_Any, memberType);
                    }
                    else if (unboxType == typeof(char))
                    {
                        generator.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToChar", new Type[] { typeof(object) }));
                    }
                    else if (unboxType == typeof(JToken))
                    {
                        generator.Emit(OpCodes.Call, typeof(JToken).GetMethod("Parse", new Type[] { typeof(string) }));
                    }
                    else
                    {
                        generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(i));
                        if (nullUnderlyingType != null)
                        {
                            generator.Emit(OpCodes.Newobj, memberType.GetConstructor(new[] { nullUnderlyingType }));
                        }
                    }

                    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);
        }