Пример #1
0
        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);
        }
Пример #2
0
        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);
        }