internal static Func <IDataReader, TModel> GetMapper <TModel>(IDataReader reader) { string cacheKey = GetCacheKey <TModel>(); Delegate mapper; if (ModelMappers.TryGetValue(cacheKey, out mapper)) { return(mapper as Func <IDataReader, TModel>); } var m = new DynamicMethod(string.Format("__model_mapper_{0}", ModelMappers.Count), typeof(TModel), new[] { typeof(IDataReader) }, true); var il = m.GetILGenerator(); il.DeclareLocal(typeof(TModel)); var ctor = typeof(TModel).GetConstructor(Type.EmptyTypes); il.Emit(OpCodes.Newobj, ctor); il.Emit(OpCodes.Stloc_0); var getValue = typeof(IDataRecord).GetMethod("GetValue", new Type[] { typeof(int) }); for (int i = 0; i < reader.FieldCount; i++) { var sourceType = reader.GetFieldType(i); var sourceName = reader.GetName(i); var outputProperty = (from p in typeof(TModel).GetProperties(BindingFlags.Public | BindingFlags.Instance) where SqlGenerationUtility.GetColumnName(p) == sourceName && p.PropertyType == sourceType select p).FirstOrDefault(); if (outputProperty == null) { continue; } MethodInfo setValue = outputProperty.GetSetMethod(); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldc_I4, i); il.Emit(OpCodes.Callvirt, getValue); il.Emit(OpCodes.Unbox_Any, sourceType); il.Emit(OpCodes.Callvirt, setValue); } il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ret); TestShowVisualizer(m); var @delegate = m.CreateDelegate(typeof(Func <IDataReader, TModel>)); ModelMappers[cacheKey] = @delegate; return(@delegate as Func <IDataReader, TModel>); }
private static IEnumerable <Tuple <MemberInfo, string> > GetColumnInformationForModel <TModel>() { string cacheKey = GetCacheKey <TModel>(); List <Tuple <MemberInfo, string> > columnNames; if (ColumnNames.TryGetValue(cacheKey, out columnNames)) { return(columnNames); } var modelProperties = typeof(TModel).GetProperties(BindingFlags.Public | BindingFlags.Instance); columnNames = (from p in modelProperties select new Tuple <MemberInfo, string>(p, SqlGenerationUtility.GetColumnName(p))).ToList(); ColumnNames[cacheKey] = columnNames; return(columnNames); }