public static Func <IDataReader, object> GetInitModelByReader(Type type, IDataReader reader) { Type[] parameterTypes = new Type[] { typeof(IDataReader) }; DynamicMethod method = new DynamicMethod(string.Format("Deserialize{0}", Guid.NewGuid()), typeof(object), parameterTypes, true); ILGenerator iLGenerator = method.GetILGenerator(); iLGenerator.DeclareLocal(typeof(int)); iLGenerator.DeclareLocal(type); iLGenerator.Emit(OpCodes.Ldc_I4_0); iLGenerator.Emit(OpCodes.Stloc_0); DataMap dataMap = Metadata.GetDataMap(type); string[] names = (from i in Enumerable.Range(0, reader.FieldCount) select reader.GetName(i)) .Where(e => e != "RN" && (dataMap._properties.Where(p => p.Name == e).Count() > 0 || dataMap._columnAttributes.Where(p => p.columnName == e).Count() > 0)).Distinct().ToArray <string>(); ConstructorInfo info = dataMap.FindConstructor(); iLGenerator.Emit(OpCodes.Newobj, info); iLGenerator.Emit(OpCodes.Stloc_1); iLGenerator.BeginExceptionBlock(); int num = 0; int localIndex = iLGenerator.DeclareLocal(typeof(object)).LocalIndex; foreach (ColumnMap map in (from n in names select dataMap.GetMember(n)).ToList <ColumnMap>()) { //var labelElse = iLGenerator.DefineLabel(); //var labelEnd = iLGenerator.DefineLabel(); iLGenerator.Emit(OpCodes.Ldarg_0);//加载reader iLGenerator.Emit(OpCodes.Ldstr, map.MemberName); MethodInfo getValueMethod = typeof(IDataRecord).GetMethod("get_Item", new[] { typeof(string) }); iLGenerator.Emit(OpCodes.Callvirt, getValueMethod); iLGenerator.Emit(OpCodes.Stloc, (short)localIndex); iLGenerator.Emit(OpCodes.Ldloc_1);//压入对象 iLGenerator.Emit(OpCodes.Ldloc, localIndex); iLGenerator.Emit(OpCodes.Dup); Label notNullLabel = iLGenerator.DefineLabel(); iLGenerator.Emit(OpCodes.Isinst, typeof(DBNull)); //是1,否0 iLGenerator.Emit(OpCodes.Brfalse_S, notNullLabel); //如果非空、非0则控制权转到label iLGenerator.Emit(OpCodes.Pop); iLGenerator.Emit(OpCodes.Ldstr, "0"); iLGenerator.Emit(OpCodes.Stloc, localIndex); iLGenerator.Emit(OpCodes.Ldloc, localIndex); iLGenerator.Emit(OpCodes.Br_S, notNullLabel); iLGenerator.MarkLabel(notNullLabel); iLGenerator.Emit(OpCodes.Call, typeof(Convert).GetMethod(typeMap[map.MemberType], new Type[] { typeof(object) })); iLGenerator.Emit(OpCodes.Callvirt, map.SetMethodInfo); num++; } iLGenerator.BeginCatchBlock(typeof(Exception)); iLGenerator.EmitCall(OpCodes.Call, typeof(Check).GetMethod("ThrowDataException"), null); iLGenerator.EndExceptionBlock(); //iLGenerator.Emit(OpCodes.Ldloc, localIndex); iLGenerator.Emit(OpCodes.Ldloc_1); iLGenerator.Emit(OpCodes.Ret); return((Func <IDataReader, object>)method.CreateDelegate(typeof(Func <IDataReader, object>))); }
private static Func <object, string> CreateInsertMethodImpl(object model) { Type type = model.GetType(); DynamicMethod method = new DynamicMethod(string.Format("Update{0}", Guid.NewGuid()), typeof(string), new Type[] { typeof(object) }, true); var iLGenerator = method.GetILGenerator(); iLGenerator.DeclareLocal(typeof(StringBuilder)); iLGenerator.Emit(OpCodes.Newobj, typeof(StringBuilder).GetConstructor(new Type[] { })); iLGenerator.Emit(OpCodes.Stloc_0); iLGenerator.DeclareLocal(typeof(StringBuilder)); iLGenerator.Emit(OpCodes.Newobj, typeof(StringBuilder).GetConstructor(new Type[] { })); iLGenerator.Emit(OpCodes.Stloc_1); DataMap map = Metadata.GetDataMap(model.GetType()); iLGenerator.BeginExceptionBlock(); var indexlocal = iLGenerator.DeclareLocal(typeof(string)); var indexlocalInt32 = iLGenerator.DeclareLocal(typeof(Int32)); var indexlocalSecond = iLGenerator.DeclareLocal(typeof(string)); foreach (ColumnMap item in (from p in map._properties select(map.GetMember(p.Name)))) { if (!item.isAutoIncrement) { iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Unbox_Any, type); iLGenerator.Emit(OpCodes.Callvirt, item.GetMethodInfo); if (item.MemberType == typeof(Int32)) { iLGenerator.Emit(OpCodes.Stloc, indexlocalInt32); iLGenerator.Emit(OpCodes.Ldloca_S, indexlocalInt32); } if (item.MemberType == typeof(Boolean)) { iLGenerator.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(Boolean) })); iLGenerator.Emit(OpCodes.Stloc, indexlocalInt32); iLGenerator.Emit(OpCodes.Ldloca_S, indexlocalInt32); } if (item.MemberType == typeof(Boolean)) { iLGenerator.Emit(OpCodes.Call, typeof(Int32).GetMethod("ToString", new Type[] { })); } else { iLGenerator.Emit(OpCodes.Call, item.MemberType.GetMethod("ToString", new Type[] { })); } iLGenerator.Emit(OpCodes.Stloc, indexlocal); iLGenerator.Emit(OpCodes.Ldstr, CreateFormatParamByType(item.MemberType)); iLGenerator.Emit(OpCodes.Ldloc, indexlocal); iLGenerator.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), item.MemberType })); iLGenerator.Emit(OpCodes.Stloc, indexlocal); iLGenerator.Emit(OpCodes.Ldloc_0); iLGenerator.Emit(OpCodes.Ldloc, indexlocal); iLGenerator.Emit(OpCodes.Callvirt, typeof(StringBuilder).GetMethod("Append", new Type[] { typeof(string) })); iLGenerator.Emit(OpCodes.Stloc_0); iLGenerator.Emit(OpCodes.Ldstr, "{0},"); iLGenerator.Emit(OpCodes.Ldstr, item.MemberName); iLGenerator.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), item.MemberType })); iLGenerator.Emit(OpCodes.Stloc, indexlocalSecond); iLGenerator.Emit(OpCodes.Ldloc_1); iLGenerator.Emit(OpCodes.Ldloc, indexlocalSecond); iLGenerator.Emit(OpCodes.Callvirt, typeof(StringBuilder).GetMethod("Append", new Type[] { typeof(string) })); iLGenerator.Emit(OpCodes.Stloc_1); } } iLGenerator.BeginCatchBlock(typeof(Exception)); iLGenerator.EmitCall(OpCodes.Call, typeof(Check).GetMethod("ThrowDataException"), null); iLGenerator.EndExceptionBlock(); iLGenerator.Emit(OpCodes.Ldloc_0); iLGenerator.Emit(OpCodes.Callvirt, typeof(StringBuilder).GetMethod("ToString", new Type[] { })); iLGenerator.Emit(OpCodes.Call, typeof(SqlMapper).GetMethod("RemoveComma", new Type[] { typeof(string) })); iLGenerator.Emit(OpCodes.Stloc, indexlocal); iLGenerator.Emit(OpCodes.Ldloc_1); iLGenerator.Emit(OpCodes.Callvirt, typeof(StringBuilder).GetMethod("ToString", new Type[] { })); iLGenerator.Emit(OpCodes.Call, typeof(SqlMapper).GetMethod("RemoveComma", new Type[] { typeof(string) })); iLGenerator.Emit(OpCodes.Stloc, indexlocalSecond); iLGenerator.Emit(OpCodes.Ldstr, "INSERT INTO {0} ({1}) VALUES ({2})"); iLGenerator.Emit(OpCodes.Ldstr, map.tableName); iLGenerator.Emit(OpCodes.Ldloc, indexlocalSecond); iLGenerator.Emit(OpCodes.Ldloc, indexlocal); iLGenerator.Emit(OpCodes.Call, typeof(string).GetMethod("Format", new Type[] { typeof(string), typeof(string), typeof(string), typeof(string) })); iLGenerator.Emit(OpCodes.Ret); return((Func <object, string>)method.CreateDelegate(typeof(Func <object, string>))); }
public static Func <object, string> CreateUpdateSqlMethodImpl(object model) { Type type = model.GetType(); DynamicMethod method = new DynamicMethod(string.Format("Update{0}", Guid.NewGuid()), typeof(string), new Type[] { typeof(object) }, true); var iLGenerator = method.GetILGenerator(); iLGenerator.DeclareLocal(typeof(StringBuilder)); iLGenerator.Emit(OpCodes.Newobj, typeof(StringBuilder).GetConstructor(new Type[] { })); iLGenerator.Emit(OpCodes.Stloc_0); DataMap map = Metadata.GetDataMap(model.GetType()); iLGenerator.Emit(OpCodes.Ldloc_0); iLGenerator.Emit(OpCodes.Ldstr, "update " + map.tableName + " set "); iLGenerator.Emit(OpCodes.Callvirt, typeof(StringBuilder).GetMethod("Append", new Type[] { typeof(string) })); iLGenerator.Emit(OpCodes.Stloc_0); iLGenerator.BeginExceptionBlock(); var indexlocal = iLGenerator.DeclareLocal(typeof(string)); var indexlocalInt32 = iLGenerator.DeclareLocal(typeof(Int32)); foreach (ColumnMap item in (from p in map._properties select(map.GetMember(p.Name)))) { if (!item.isPrimaryKey) { iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Unbox_Any, type); iLGenerator.Emit(OpCodes.Callvirt, item.GetMethodInfo); if (item.MemberType == typeof(Int32)) { iLGenerator.Emit(OpCodes.Stloc, indexlocalInt32); iLGenerator.Emit(OpCodes.Ldloca_S, indexlocalInt32); } if (item.MemberType == typeof(Boolean)) { iLGenerator.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToInt32", new Type[] { typeof(Boolean) })); iLGenerator.Emit(OpCodes.Stloc, indexlocalInt32); iLGenerator.Emit(OpCodes.Ldloca_S, indexlocalInt32); } if (item.MemberType == typeof(Boolean)) { iLGenerator.Emit(OpCodes.Call, typeof(Int32).GetMethod("ToString", new Type[] { })); } else { iLGenerator.Emit(OpCodes.Call, item.MemberType.GetMethod("ToString", new Type[] { })); } iLGenerator.Emit(OpCodes.Stloc, indexlocal); iLGenerator.Emit(OpCodes.Ldstr, item.MemberName + (item.MemberType == typeof(Int32) || item.MemberType == typeof(Boolean)?"=":"='")); iLGenerator.Emit(OpCodes.Ldloc, indexlocal); iLGenerator.Emit(OpCodes.Ldstr, item.MemberType == typeof(Int32) || item.MemberType == typeof(Boolean)?",":"',"); iLGenerator.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(object), typeof(object), typeof(object) })); iLGenerator.Emit(OpCodes.Stloc, indexlocal); iLGenerator.Emit(OpCodes.Ldloc_0); iLGenerator.Emit(OpCodes.Ldloc, indexlocal); iLGenerator.Emit(OpCodes.Callvirt, typeof(StringBuilder).GetMethod("Append", new Type[] { typeof(string) })); iLGenerator.Emit(OpCodes.Stloc_0); } } iLGenerator.BeginCatchBlock(typeof(Exception)); iLGenerator.EmitCall(OpCodes.Call, typeof(Check).GetMethod("ThrowDataException"), null); iLGenerator.EndExceptionBlock(); iLGenerator.Emit(OpCodes.Ldloc_0); iLGenerator.Emit(OpCodes.Callvirt, typeof(StringBuilder).GetMethod("ToString", new Type[] { })); iLGenerator.Emit(OpCodes.Call, typeof(SqlMapper).GetMethod("RemoveComma", new Type[] { typeof(string) })); iLGenerator.Emit(OpCodes.Ret); return((Func <object, string>)method.CreateDelegate(typeof(Func <object, string>))); }