示例#1
0
        /// <summary>
        /// 设置DataRow转Entity的IL
        /// </summary>
        /// <param name="instanceType">实例类型</param>
        /// <param name="il"></param>
        /// <param name="currentRowBuilder">当前DataRow</param>
        /// <param name="instanceBuilder">实例的本地变量</param>
        public static void SetDataRowToEntityIL(this ILGenerator il, Type instanceType, LocalBuilder currentRowBuilder, LocalBuilder instanceBuilder)
        {
            List <PropertyInfo> properties = PropertyUtil.GetTypeProperties(instanceType);

            foreach (var property in properties)
            {
                var setMethod = property.GetSetMethod(true);
                if (setMethod != null)
                {
                    if (TypeUtil._BaseTypes.Contains(property.PropertyType) || property.PropertyType.IsEnum)
                    {
                        Label endIfLabel = il.DefineLabel();

                        //判断是否包含此属性,不区分大小写,不包含则直接调到结束位置
                        il.Emit(OpCodes.Ldloc, currentRowBuilder);
                        il.Emit(OpCodes.Ldstr, property.Name);
                        il.Emit(OpCodes.Call, DataTableUtil.IsContainColumnMethod);
                        il.Emit(OpCodes.Brfalse, endIfLabel);

                        //获取此属性在dataRow中的值,并赋值
                        LoadDefaultObject(il, instanceType, instanceBuilder);
                        il.Emit(OpCodes.Ldloc, currentRowBuilder);
                        il.Emit(OpCodes.Ldstr, property.Name);
                        il.Emit(OpCodes.Call, DataTableUtil.GetColumnValueMethod);
                        //值进行转换
                        ConvertValue(il, property.PropertyType);
                        SetObjectValue(il, instanceType, setMethod);

                        //结束
                        il.MarkLabel(endIfLabel);
                    }
                    else if (property.PropertyType.IsArrayOrCollection())//数组类型
                    {
                    }
                    else//对象
                    {
                        LocalBuilder instanceProperty = il.DeclareLocal(property.PropertyType);
                        SetDefaultObjectValue(il, property.PropertyType, instanceProperty);//实例对象
                        SetDataRowToEntityIL(il, property.PropertyType, currentRowBuilder, instanceProperty);
                        LoadDefaultObject(il, instanceType, instanceBuilder);
                        il.Emit(OpCodes.Ldloc, instanceProperty);
                        SetObjectValue(il, instanceType, setMethod);
                    }
                }
            }
        }
示例#2
0
        private static void SetDataRowIL(Type instanceType, ILGenerator il, LocalBuilder currentRowBuilder, LocalBuilder instanceBuilder)
        {
            List <PropertyInfo> properties = PropertyUtil.GetTypeProperties(instanceType);

            foreach (var item in properties.Where(m => TypeUtil._BaseTypes.Contains(m.PropertyType) || m.PropertyType.IsEnum))
            {
                if (item.GetSetMethod(true) != null)//如果有设置属性的方法
                {
                    Label endIfLabel = il.DefineLabel();

                    //判断DataRow是否包含该属性

                    il.Emit(OpCodes.Ldloc, currentRowBuilder);
                    il.Emit(OpCodes.Ldstr, item.Name);
                    il.Emit(OpCodes.Call, DataTableUtil.IsContainColumnMethod);
                    il.Emit(OpCodes.Brfalse, endIfLabel);

                    //获取该属性在datarow的值
                    il.Emit(OpCodes.Ldloc, instanceBuilder);

                    il.Emit(OpCodes.Ldloc, currentRowBuilder);
                    il.Emit(OpCodes.Ldstr, item.Name);
                    il.Emit(OpCodes.Call, DataTableUtil.GetColumnValueMethod);

                    //设置值
                    if (item.PropertyType.IsValueType)
                    {
                        var convertMethod = ConvertUtil.GetMethodInfo(item.PropertyType);
                        if (convertMethod == null)
                        {
                            il.Emit(OpCodes.Unbox_Any, item.PropertyType);//如果是值类型就拆箱
                        }
                        else
                        {
                            il.Emit(OpCodes.Call, convertMethod);
                        }
                    }
                    else
                    {
                        il.Emit(OpCodes.Castclass, item.PropertyType);
                    }
                    il.Emit(OpCodes.Callvirt, item.GetSetMethod(true));
                    il.MarkLabel(endIfLabel);
                }
            }

            foreach (var item in properties.Where(m => !(TypeUtil._BaseTypes.Contains(m.PropertyType) || m.PropertyType.IsEnum)))
            {
                if (item.PropertyType.IsArray || item.PropertyType.IsGenericType)
                {
                }
                else
                {
                    if (item.GetSetMethod(true) != null)
                    {
                        LocalBuilder instanceProperty = il.DeclareLocal(item.PropertyType);
                        il.Emit(OpCodes.Newobj, item.PropertyType.GetConstructor(Type.EmptyTypes));
                        il.Emit(OpCodes.Stloc, instanceProperty);
                        SetDataRowIL(item.PropertyType, il, currentRowBuilder, instanceProperty);

                        il.Emit(OpCodes.Ldloc, instanceBuilder);
                        il.Emit(OpCodes.Ldloc, instanceProperty);
                        il.Emit(OpCodes.Castclass, item.PropertyType);
                        il.Emit(OpCodes.Callvirt, item.GetSetMethod(true));
                    }
                }
            }
        }
示例#3
0
        public static DynamicMethod CreateObjectToParamListMethod <TParam>(Type objType) where TParam : DbParameter
        {
            var listType     = typeof(List <TParam>);
            var instanceType = typeof(TParam);
            //三个参数,第一个参数是object,第二个参数是参数符号(@,:,?),参数前缀
            DynamicMethod convertMethod = new DynamicMethod("ConvertObjectToParamList" + objType.Name, listType, new Type[] { TypeUtil._ObjectType, TypeUtil._StringType, TypeUtil._StringType });

            ILGenerator  il          = convertMethod.GetILGenerator();
            LocalBuilder listBuilder = il.DeclareLocal(listType);//List<T> 存储对象

            il.Emit(OpCodes.Newobj, listType.GetConstructor(Type.EmptyTypes));
            il.Emit(OpCodes.Stloc_S, listBuilder);

            LocalBuilder objBuilder = il.DeclareLocal(objType);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Unbox_Any, objType);
            il.Emit(OpCodes.Stloc, objBuilder);

            LocalBuilder dbNullBuilder = il.DeclareLocal(TypeUtil._ObjectType);

            il.Emit(OpCodes.Ldtoken, typeof(DBNull).GetField("Value"));
            il.Emit(OpCodes.Call, typeof(FieldInfo).GetMethod("GetFieldFromHandle", new Type[] { typeof(RuntimeFieldHandle) }));
            il.Emit(OpCodes.Stloc, dbNullBuilder);

            List <PropertyInfo> properties = PropertyUtil.GetTypeProperties(objType);

            foreach (var item in properties)
            {
                Label setDbNullLable = il.DefineLabel();                                                                                                          //设置dbnull
                Label setParamLable  = il.DefineLabel();                                                                                                          //给param赋值
                Label exitLable      = il.DefineLabel();                                                                                                          //退出

                bool         isNUllable       = item.PropertyType.IsGenericType && item.PropertyType.GetGenericTypeDefinition() == TypeUtil._NullableGenericType; //是否为可空的
                LocalBuilder paramNameBuilder = il.DeclareLocal(TypeUtil._StringType);                                                                            //参数变量名字
                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Ldarg_2);
                if (isNUllable)
                {
                    il.Emit(OpCodes.Ldstr, item.PropertyType.GetGenericArguments()[0].Name);
                }
                else
                {
                    il.Emit(OpCodes.Ldstr, item.Name);
                }
                il.Emit(OpCodes.Call, TypeUtil._StringType.GetMethod("Concat", new Type[] { TypeUtil._StringType, TypeUtil._StringType, TypeUtil._StringType }));
                il.Emit(OpCodes.Stloc, paramNameBuilder);

                LocalBuilder instanceBuilder = il.DeclareLocal(instanceType);// T 存储对象
                il.Emit(OpCodes.Newobj, instanceType.GetConstructor(Type.EmptyTypes));
                il.Emit(OpCodes.Stloc_S, instanceBuilder);

                LocalBuilder dbTypeBuilder = il.DeclareLocal(TypeUtil._DbTypeType);
                Ldc(il, (int)TypeUtil.Type2DbType(item.PropertyType));//数据库类型
                il.Emit(OpCodes.Stloc, dbTypeBuilder);

                //设置dbType
                il.Emit(OpCodes.Ldloc, instanceBuilder);
                il.Emit(OpCodes.Ldloc, dbTypeBuilder);
                il.Emit(OpCodes.Callvirt, instanceType.GetMethod("set_DbType", new Type[] { TypeUtil._DbTypeType }));
                //设置ParameterName
                il.Emit(OpCodes.Ldloc, instanceBuilder);
                il.Emit(OpCodes.Ldloc, paramNameBuilder);
                il.Emit(OpCodes.Callvirt, instanceType.GetMethod("set_ParameterName", new Type[] { TypeUtil._StringType }));

                il.Emit(OpCodes.Nop);

                LocalBuilder dbValueBuilder = il.DeclareLocal(TypeUtil._ObjectType);
                if (item.GetGetMethod() == null)
                {
                    il.Emit(OpCodes.Br_S, setDbNullLable);
                }
                else
                {
                    il.Emit(OpCodes.Ldloc, objBuilder);
                    il.Emit(OpCodes.Call, item.GetGetMethod());
                    if (item.PropertyType.IsValueType)
                    {
                        il.Emit(OpCodes.Box, item.PropertyType);
                        if (item.PropertyType.IsEnum)
                        {
                            il.Emit(OpCodes.Ldstr, "d");
                            il.Emit(OpCodes.Call, typeof(Enum).GetMethod("ToString", new Type[] { TypeUtil._StringType }));
                        }
                    }
                    il.Emit(OpCodes.Stloc, dbValueBuilder);
                    il.Emit(OpCodes.Ldloc, dbValueBuilder);
                    il.Emit(OpCodes.Ldnull);
                    il.Emit(OpCodes.Beq_S, setDbNullLable);
                    il.Emit(OpCodes.Br_S, setParamLable);
                }
                il.MarkLabel(setDbNullLable);
                il.Emit(OpCodes.Ldloc, dbNullBuilder);
                il.Emit(OpCodes.Stloc, dbValueBuilder);
                il.Emit(OpCodes.Br_S, setParamLable);

                il.MarkLabel(setParamLable);
                il.Emit(OpCodes.Ldloc, instanceBuilder);
                il.Emit(OpCodes.Ldloc, dbValueBuilder);
                il.Emit(OpCodes.Callvirt, instanceType.GetMethod("set_Value", new Type[] { TypeUtil._ObjectType }));

                il.Emit(OpCodes.Ldloc, listBuilder);
                il.Emit(OpCodes.Ldloc, instanceBuilder);
                il.Emit(OpCodes.Call, listType.GetMethod("Add"));
            }
            il.Emit(OpCodes.Ldloc, listBuilder);
            il.Emit(OpCodes.Ret);
            return(convertMethod);
        }
示例#4
0
        public static DynamicMethod CreateObjectToParamListMethod <TParam>(Type objType) where TParam : DbParameter
        {
            var listType     = typeof(List <TParam>);
            var instanceType = typeof(TParam);
            //三个参数,第一个参数是object,第二个参数是参数符号(@,:,?),参数前缀
            DynamicMethod convertMethod = new DynamicMethod("ConvertObjectToParamList" + objType.Name, listType, new Type[] { TypeUtil._ObjectType, TypeUtil._StringType, TypeUtil._StringType }, true);

            ILGenerator  il          = convertMethod.GetILGenerator();
            LocalBuilder listBuilder = il.DeclareLocal(listType);//List<T> 存储对象

            il.SetDefaultObjectValue(listType, listBuilder);

            LocalBuilder objBuilder = il.DeclareLocal(objType);

            il.Emit(OpCodes.Ldarg_0);
            il.SetObjectCastIL(objType);
            il.Emit(OpCodes.Stloc, objBuilder);

            LocalBuilder dbNullBuilder = il.SetDbNullIL();

            List <PropertyInfo> properties = PropertyUtil.GetTypeProperties(objType);

            foreach (var item in properties)
            {
                Label setDbNullLable = il.DefineLabel();                               //设置dbnull
                Label setParamLable  = il.DefineLabel();                               //给param赋值
                Label exitLable      = il.DefineLabel();                               //退出

                LocalBuilder paramNameBuilder = il.DeclareLocal(TypeUtil._StringType); //参数变量名字
                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Ldstr, item.Name);
                il.Emit(OpCodes.Call, TypeUtil._StringType.GetMethod("Concat", new Type[] { TypeUtil._StringType, TypeUtil._StringType, TypeUtil._StringType }));
                il.Emit(OpCodes.Stloc, paramNameBuilder);

                LocalBuilder instanceBuilder = il.DeclareLocal(instanceType);// T 存储对象
                il.SetDefaultObjectValue(instanceType, instanceBuilder);

                LocalBuilder dbTypeBuilder = il.DeclareLocal(TypeUtil._DbTypeType);
                il.LdcInt((int)TypeUtil.Type2DbType(item.PropertyType));//数据库类型
                il.Emit(OpCodes.Stloc, dbTypeBuilder);

                //设置dbType
                il.Emit(OpCodes.Ldloc, instanceBuilder);
                il.Emit(OpCodes.Ldloc, dbTypeBuilder);
                il.Emit(OpCodes.Callvirt, instanceType.GetMethod("set_DbType", new Type[] { TypeUtil._DbTypeType }));
                //设置ParameterName
                il.Emit(OpCodes.Ldloc, instanceBuilder);
                il.Emit(OpCodes.Ldloc, paramNameBuilder);
                il.Emit(OpCodes.Callvirt, instanceType.GetMethod("set_ParameterName", new Type[] { TypeUtil._StringType }));

                il.Emit(OpCodes.Nop);

                LocalBuilder dbValueBuilder = il.DeclareLocal(TypeUtil._ObjectType);
                var          getMethod      = item.GetGetMethod(true);
                if (getMethod == null)
                {
                    il.Emit(OpCodes.Br_S, setDbNullLable);
                }
                else
                {
                    il.Emit(OpCodes.Ldloc, objBuilder);
                    if (item.DeclaringType.IsValueType && Nullable.GetUnderlyingType(item.DeclaringType) == null)
                    {
                        var t = il.DeclareLocal(item.DeclaringType);
                        il.Emit(OpCodes.Stloc, t);
                        il.Emit(OpCodes.Ldloca_S, t);
                    }
                    if (item.DeclaringType.IsValueType)
                    {
                        il.Emit(OpCodes.Call, getMethod);
                    }
                    else
                    {
                        il.Emit(OpCodes.Callvirt, getMethod);
                    }

                    if (item.PropertyType.IsValueType)
                    {
                        il.Emit(OpCodes.Box, item.PropertyType);
                        if (item.PropertyType.IsEnum)
                        {
                            il.Emit(OpCodes.Ldstr, "d");
                            il.Emit(OpCodes.Call, typeof(Enum).GetMethod("ToString", new Type[] { TypeUtil._StringType }));
                        }
                    }
                    il.Emit(OpCodes.Stloc, dbValueBuilder);
                    il.Emit(OpCodes.Ldloc, dbValueBuilder);
                    il.Emit(OpCodes.Ldnull);
                    il.Emit(OpCodes.Beq_S, setDbNullLable);
                    il.Emit(OpCodes.Br_S, setParamLable);
                }
                il.MarkLabel(setDbNullLable);
                il.Emit(OpCodes.Ldloc, dbNullBuilder);
                il.Emit(OpCodes.Stloc, dbValueBuilder);
                il.Emit(OpCodes.Br_S, setParamLable);

                il.MarkLabel(setParamLable);
                il.Emit(OpCodes.Ldloc, instanceBuilder);
                il.Emit(OpCodes.Ldloc, dbValueBuilder);
                il.Emit(OpCodes.Callvirt, instanceType.GetMethod("set_Value", new Type[] { TypeUtil._ObjectType }));

                il.Emit(OpCodes.Ldloc, listBuilder);
                il.Emit(OpCodes.Ldloc, instanceBuilder);
                il.Emit(OpCodes.Call, listType.GetMethod("Add"));
            }
            il.Emit(OpCodes.Ldloc, listBuilder);
            il.Emit(OpCodes.Ret);
            return(convertMethod);
        }