private static ReadFieldInfo[] GetDataReaderFieldInfo(IDataReader Reader) { ReadFieldInfo[] Fields = new ReadFieldInfo[Reader.FieldCount]; var count = Reader.FieldCount; for (int i = 0; i < count; i++) { Type dbType = Reader.GetFieldType(i); Type CsType; //////不同数据库类型与CSharp类型对应 if (DBTypeMapping.TryGetValue(dbType, out CsType)) { Fields[i] = new ReadFieldInfo() { FieldIndex = i, FieldName = Reader.GetName(i), FieldType = CsType }; } else { Fields[i] = new ReadFieldInfo() { FieldIndex = i, FieldName = Reader.GetName(i), FieldType = dbType }; } } return(Fields); }
public static Func <IDataReader, T> GetCreator <T>(IDataReader Reader) { object func = null; Type classType = typeof(T); ReadFieldInfo[] FieldInfos = GetDataReaderFieldInfo(Reader); StringBuilder sber = new StringBuilder().Append(classType.GetHashCode()); for (int c = 0; c < FieldInfos.Length; c++) { sber.Append(FieldInfos[c].FieldType.Name); } if (CreatorsCache.TryGetValue(sber.ToString(), out func)) { return((Func <IDataReader, T>)func); } var ppIndex = new List <ODAPropertyInfo>(); PropertyInfo[] prptys = classType.GetProperties(BindingFlags.Instance | BindingFlags.Public); for (int i = 0; i < prptys.Length; i++) { if (prptys[i].CanWrite) { ppIndex.Add(new ODAPropertyInfo(prptys[i])); } } DynamicMethod method; if (classType.IsInterface) { method = new DynamicMethod("Create" + classType.Name, classType, new Type[] { typeof(IDataReader) }, classType.Module, true); } else { method = new DynamicMethod("Create" + classType.Name, classType, new Type[] { typeof(IDataReader) }, classType, true); } ILGenerator il = method.GetILGenerator(); LocalBuilder result = il.DeclareLocal(classType); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Newobj, classType.GetConstructor(Type.EmptyTypes)); il.Emit(OpCodes.Stloc, result); for (int i = 0; i < ppIndex.Count; i++) { ReadFieldInfo Field = null; foreach (var fld in FieldInfos) { if (fld.FieldName == ppIndex[i].PropertyName) { Field = fld; break; } } var setter = ppIndex[i].OriginProperty.GetSetMethod(true); if (setter != null && Field != null) { Label lb = il.DefineLabel(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4, Field.FieldIndex); il.Emit(OpCodes.Callvirt, IsDBNull); il.Emit(OpCodes.Brtrue, lb); il.Emit(OpCodes.Ldloc, result); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4, Field.FieldIndex); BindReaderMethod(il, ppIndex[i], Field.FieldType); if (setter.IsFinal || !setter.IsVirtual) { il.Emit(OpCodes.Call, setter); } else { il.Emit(OpCodes.Callvirt, setter); } il.MarkLabel(lb); } } il.Emit(OpCodes.Ldloc, result); il.Emit(OpCodes.Ret); object reator = method.CreateDelegate(typeof(Func <IDataReader, T>)); CreatorsCache.Add(sber.ToString(), reator); GC.KeepAlive(reator); return((Func <IDataReader, T>)reator); }