예제 #1
0
 /// <summary>
 /// Returns attribute information based on field information
 /// </summary>
 public MemberInfo FindMember(MemberInfo[] properties, DbDataInfo dataInfo)
 {
     foreach (var item in properties)
     {
         if (item.Name.Equals(dataInfo.DataName, StringComparison.OrdinalIgnoreCase))
         {
             return(item);
         }
         else if (//SqlMapper.MatchNamesWithUnderscores &&
             item.Name.Equals(dataInfo.DataName.Replace("_", ""), StringComparison.OrdinalIgnoreCase))
         {
             return(item);
         }
     }
     return(null);
 }
예제 #2
0
        private static Func <IDataRecord, T> CreateTypeSerializerHandler <T>(ITypeMapper mapper, IDataRecord record)
        {
            var          type          = typeof(T);
            var          methodName    = $"{type.Name}Serializer{Guid.NewGuid().ToString("N")}";
            var          dynamicMethod = new DynamicMethod(methodName, type, new Type[] { typeof(IDataRecord) }, type, true);
            var          generator     = dynamicMethod.GetILGenerator();
            LocalBuilder local         = generator.DeclareLocal(type);
            var          dataInfos     = new DbDataInfo[record.FieldCount];

            for (int i = 0; i < record.FieldCount; i++)
            {
                var dataname = record.GetName(i);
                var datatype = record.GetFieldType(i);
                var typename = record.GetDataTypeName(i);
                dataInfos[i] = new DbDataInfo(i, typename, datatype, dataname);
            }
            if (dataInfos.Length == 1 && (type.IsValueType || type == typeof(string) || type == typeof(object)))
            {
                var dataInfo      = dataInfos.First();
                var convertMethod = mapper.FindConvertMethod(type, dataInfo.DataType);
                generator.Emit(OpCodes.Ldarg_0);
                generator.Emit(OpCodes.Ldc_I4, 0);
                if (convertMethod.IsVirtual)
                {
                    generator.Emit(OpCodes.Callvirt, convertMethod);
                }
                else
                {
                    generator.Emit(OpCodes.Call, convertMethod);
                }
                generator.Emit(OpCodes.Stloc, local);
                generator.Emit(OpCodes.Ldloc, local);
                generator.Emit(OpCodes.Ret);
                return(dynamicMethod.CreateDelegate(typeof(Func <IDataRecord, T>)) as Func <IDataRecord, T>);
            }
            var constructor = mapper.FindConstructor(type);

            if (constructor.GetParameters().Length > 0)
            {
                var parameters = constructor.GetParameters();
                var locals     = new LocalBuilder[parameters.Length];
                for (int i = 0; i < locals.Length; i++)
                {
                    locals[i] = generator.DeclareLocal(parameters[i].ParameterType);
                }
                for (int i = 0; i < locals.Length; i++)
                {
                    var item = mapper.FindConstructorParameter(dataInfos, parameters[i]);
                    if (item == null)
                    {
                        continue;
                    }
                    var convertMethod = mapper.FindConvertMethod(parameters[i].ParameterType, item.DataType);
                    generator.Emit(OpCodes.Ldarg_0);
                    generator.Emit(OpCodes.Ldc_I4, item.Ordinal);
                    if (convertMethod.IsVirtual)
                    {
                        generator.Emit(OpCodes.Callvirt, convertMethod);
                    }
                    else
                    {
                        generator.Emit(OpCodes.Call, convertMethod);
                    }
                    generator.Emit(OpCodes.Stloc, locals[i]);
                }
                for (int i = 0; i < locals.Length; i++)
                {
                    generator.Emit(OpCodes.Ldloc, locals[i]);
                }
                generator.Emit(OpCodes.Newobj, constructor);
                generator.Emit(OpCodes.Stloc, local);
                generator.Emit(OpCodes.Ldloc, local);
                generator.Emit(OpCodes.Ret);
                return(dynamicMethod.CreateDelegate(typeof(Func <IDataRecord, T>)) as Func <IDataRecord, T>);
            }
            else
            {
                var properties = type.GetProperties();
                generator.Emit(OpCodes.Newobj, constructor);
                generator.Emit(OpCodes.Stloc, local);
                foreach (var item in dataInfos)
                {
                    var property = mapper.FindMember(properties, item) as PropertyInfo;
                    if (property == null)
                    {
                        continue;
                    }
                    var convertMethod = mapper.FindConvertMethod(property.PropertyType, item.DataType);
                    if (convertMethod == null)
                    {
                        continue;
                    }
                    int i = record.GetOrdinal(item.DataName);
                    generator.Emit(OpCodes.Ldloc, local);
                    generator.Emit(OpCodes.Ldarg_0);
                    generator.Emit(OpCodes.Ldc_I4, i);
                    if (convertMethod.IsVirtual)
                    {
                        generator.Emit(OpCodes.Callvirt, convertMethod);
                    }
                    else
                    {
                        generator.Emit(OpCodes.Call, convertMethod);
                    }
                    generator.Emit(OpCodes.Callvirt, property.GetSetMethod());
                }
                generator.Emit(OpCodes.Ldloc, local);
                generator.Emit(OpCodes.Ret);
                return(dynamicMethod.CreateDelegate(typeof(Func <IDataRecord, T>)) as Func <IDataRecord, T>);
            }
        }