예제 #1
0
파일: ModelUtility.cs 프로젝트: jweber/Dypo
        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>);
        }
예제 #2
0
파일: ModelUtility.cs 프로젝트: jweber/Dypo
        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);
        }