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