Exemplo n.º 1
0
        internal static Func <DbDataReader, object> GetReader(int hashKey, Type targetType, DbDataReader reader, bool isIgnoreCase)
        {
            int readerKey = GetReaderKey(targetType, hashKey);

            if (!ReaderCache.ContainsKey(readerKey))
            {
                string       propName     = null;
                PropertyInfo propInfo     = null;
                var          bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
                if (isIgnoreCase)
                {
                    bindingFlags |= BindingFlags.IgnoreCase;
                }
                List <string> propNameList = new List <string>();
                for (int i = 0; i < reader.FieldCount; i++)
                {
                    propName = reader.GetName(i);
                    propInfo = targetType.GetProperty(propName, bindingFlags);
                    if (propInfo == null)
                    {
                        continue;
                    }
                    propNameList.Add(propInfo.Name);
                }
                var readerHandler = DbTypeMap.ContainsKey(targetType) ? CreateValueReaderHandler(targetType, reader.GetOrdinal(propName)) : CreateTypeReaderHandler(targetType, propNameList, reader);
                ReaderCache.TryAdd(readerKey, readerHandler);
            }
            return(ReaderCache[readerKey]);
        }
Exemplo n.º 2
0
        private static void CreateParamter(ILGenerator il, string paramPrefix, KeyValuePair <string, object> colMapper)
        {
            il.Emit(OpCodes.Dup);
            il.Emit(OpCodes.Ldarg_0);
            il.EmitCall(OpCodes.Callvirt, typeof(IDbCommand).GetMethod(nameof(IDbCommand.CreateParameter), Type.EmptyTypes), null);

            // stack is now [parameters][parameters][parameter]
            il.Emit(OpCodes.Dup);
            il.Emit(OpCodes.Ldstr, paramPrefix + colMapper.Key);
            il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.ParameterName)).GetSetMethod(), null);
            // stack is now [parameters][parameters][parameter]

            var memberType     = colMapper.Value.GetType();
            var dbType         = DbTypeMap.LookupDbType(colMapper.Value.GetType());
            var underlyingType = memberType;
            var isValueType    = memberType.GetTypeInfo().IsValueType;
            var isEnum         = memberType.GetTypeInfo().IsEnum;
            var isNullable     = Nullable.GetUnderlyingType(memberType) != null;

            if (isNullable)
            {
                underlyingType = Nullable.GetUnderlyingType(memberType);
                isEnum         = underlyingType.GetTypeInfo().IsEnum;
            }
            var isString = underlyingType == typeof(string);

            // stack is now [parameters][parameters][parameter][parameter].DbType={DbType}
            il.Emit(OpCodes.Dup);
            LoadInt32(il, (int)dbType);
            il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.DbType)).GetSetMethod(), null);

            // stack is now [parameters][parameters][parameter][parameter].Direction={ParameterDirection.Input}
            il.Emit(OpCodes.Dup);
            LoadInt32(il, (int)ParameterDirection.Input);
            il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.Direction)).GetSetMethod(), null);

            //byte,double,float,int,long,sbyte,short,string,Type
            il.Emit(OpCodes.Dup);
            il.Emit(OpCodes.Ldloc_0);
            il.Emit(OpCodes.Ldstr, colMapper.Key);
            il.Emit(OpCodes.Call, typeof(KeyValuePair <string, object>).GetProperty(nameof(KeyValuePair <string, object> .Value)).GetGetMethod());

            // stack is now [parameters][parameters][parameter][parameter][value]
            if (memberType.GetTypeInfo().IsValueType)
            {
                il.Emit(OpCodes.Box, memberType);
                if (memberType.GetTypeInfo().IsEnum&& memberType == typeof(string))
                {
                    // stack is now [parameters][parameters][parameter][parameter][int-value][enum-type]
                    il.Emit(OpCodes.Ldtoken, underlyingType);
                    il.EmitCall(OpCodes.Call, typeof(Type).GetMethod(nameof(Type.GetTypeFromHandle)), null);
                    // stack is now [parameters][parameters][parameter][parameter][int-value][enum-type]
                    il.EmitCall(OpCodes.Call, typeof(RepositoryHelper).GetMethod(nameof(RepositoryHelper.GetEnumName), BindingFlags.Static | BindingFlags.Public), null);
                    il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.Value)).GetSetMethod(), null);

                    //直接设置长度为100,枚举值都不会超过100个字符,避免了做类似下面的复杂逻辑操作
                    il.Emit(OpCodes.Dup);
                    LoadInt32(il, 100);
                    il.EmitCall(OpCodes.Callvirt, typeof(IDbDataParameter).GetProperty(nameof(IDbDataParameter.Size)).GetSetMethod(), null);

                    #region 获取字符串长度,设置长度
                    //// stack is now [parameters][parameters][parameter][parameter][string or dbNull]
                    //il.Emit(OpCodes.Dup);
                    //il.Emit(OpCodes.Isinst, typeof(DBNull));
                    //// stack is now [target][target][value][DBNull or null]
                    //Label dbNullLabel = il.DefineLabel();
                    //il.Emit(OpCodes.Brtrue_S, dbNullLabel);

                    ////非空字符串
                    //var iLocIndex = il.DeclareLocal(typeof(string)).LocalIndex;
                    //il.Emit(OpCodes.Dup);
                    //il.Emit(OpCodes.Castclass, typeof(string));
                    //il.Emit(OpCodes.Stloc, iLocIndex);
                    //il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.Value)).GetSetMethod(), null);
                    //// stack is now [parameters][parameters][parameter]

                    ////设置长度
                    //il.Emit(OpCodes.Dup);
                    //il.Emit(OpCodes.Ldloc, iLocIndex);
                    //il.EmitCall(OpCodes.Callvirt, typeof(string).GetProperty(nameof(string.Length)).GetGetMethod(), null);
                    //// stack is now [parameters][parameters][parameter][string-length]
                    //il.EmitCall(OpCodes.Callvirt, typeof(IDbDataParameter).GetProperty(nameof(IDbDataParameter.Size)).GetSetMethod(), null);

                    //Label allDoneLabel = il.DefineLabel();
                    //il.Emit(OpCodes.Br_S, allDoneLabel);

                    //il.MarkLabel(dbNullLabel);
                    //il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.Value)).GetSetMethod(), null);
                    //il.MarkLabel(allDoneLabel);
                    #endregion
                }
                else
                {
                    if (isNullable)
                    {
                        il.Emit(OpCodes.Dup);
                        Label notNullLabel = il.DefineLabel();
                        il.Emit(OpCodes.Brtrue_S, notNullLabel);
                        // stack is now [parameters][parameters][parameter]
                        il.Emit(OpCodes.Pop);
                        il.Emit(OpCodes.Ldsfld, typeof(DBNull).GetField(nameof(DBNull.Value)));
                        il.MarkLabel(notNullLabel);
                    }
                    // stack is now [parameters][parameters][parameter][parameter][object-value]
                    il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.Value)).GetSetMethod(), null);
                }
            }
            else
            {
                // stack is now [parameters][parameters][parameter]
                il.Emit(OpCodes.Dup);
                Label notNullLabel = il.DefineLabel();
                il.Emit(OpCodes.Brtrue_S, notNullLabel);
                // stack is now [parameters][parameters][parameter][parameter]
                il.Emit(OpCodes.Pop);
                il.Emit(OpCodes.Ldsfld, typeof(DBNull).GetField(nameof(DBNull.Value)));
                // stack is now [parameters][parameters][parameter][parameter][DBNull]
                il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.Value)).GetSetMethod(), null);

                Label allDoneLabel = il.DefineLabel();
                il.Emit(OpCodes.Br_S, allDoneLabel);

                //不为空
                il.MarkLabel(notNullLabel);
                int?stringIndex = null;
                if (isString)
                {
                    il.Emit(OpCodes.Dup);
                    // stack is now [parameters][parameters][parameter][parameter][string][string]
                    il.EmitCall(OpCodes.Callvirt, typeof(string).GetProperty(nameof(string.Length)).GetGetMethod(), null);
                    LoadInt32(il, 4000);
                    il.Emit(OpCodes.Cgt); // [string] [0 or 1]
                    Label isLong = il.DefineLabel(), lenDone = il.DefineLabel();
                    il.Emit(OpCodes.Brtrue_S, isLong);
                    LoadInt32(il, 4000); // [string] [4000]
                    il.Emit(OpCodes.Br_S, lenDone);
                    il.MarkLabel(isLong);
                    LoadInt32(il, -1); // [string] [-1]
                    il.MarkLabel(lenDone);

                    stringIndex = il.DeclareLocal(typeof(int)).LocalIndex;
                    il.Emit(OpCodes.Stloc_S, (byte)stringIndex);
                }
                il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.Value)).GetSetMethod(), null);

                // stack is now [parameters][parameters][parameter]
                if (isString)
                {
                    il.Emit(OpCodes.Dup);
                    // stack is now [parameters][parameters][parameter][parameter].Size=len(string)
                    il.Emit(OpCodes.Stloc_S, (byte)stringIndex);
                    il.EmitCall(OpCodes.Callvirt, typeof(IDbDataParameter).GetProperty(nameof(IDbDataParameter.Size)).GetSetMethod(), null);
                    // stack is now [parameters][parameters][parameter]
                }
                il.MarkLabel(allDoneLabel);
            }
            // stack is now [parameters][parameters].Add([parameter])
            il.EmitCall(OpCodes.Callvirt, typeof(IList).GetMethod(nameof(IList.Add)), null);
            il.Emit(OpCodes.Pop);
            // stack is now [parameters]
        }
Exemplo n.º 3
0
        public EntityMapper(Type entityType)
        {
            this.EntityType    = entityType;
            this.TableName     = entityType.Name;
            this.FieldPrefix   = String.Empty;
            this.MemberMappers = new Dictionary <string, MemberMapper>();
            this.PrimaryKeys   = new List <MemberMapper>();
            var tableAttr = entityType.GetTypeInfo().GetCustomAttribute <TableAttribute>();

            if (tableAttr != null)
            {
                if (!String.IsNullOrEmpty(tableAttr.TableName))
                {
                    this.TableName = tableAttr.TableName;
                }
                this.FieldPrefix = tableAttr.FieldPrefix;
            }
            var properties = entityType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where(p => p.GetIndexParameters().Length == 0);

            foreach (var prop in properties)
            {
                MemberMapper colMapper = new MemberMapper();
                if (prop.GetCustomAttribute <IgnoreAttribute>() != null)
                {
                    continue;
                }
                colMapper.FieldName      = this.FieldPrefix + prop.Name;
                colMapper.GetMethodInfo  = prop.GetGetMethod(true);
                colMapper.MemberName     = prop.Name;
                colMapper.MemberType     = prop.PropertyType;
                colMapper.DbType         = DbTypeMap.LookupDbType(prop.PropertyType);
                colMapper.UnderlyingType = prop.PropertyType;
                colMapper.IsValueType    = prop.PropertyType.GetTypeInfo().IsValueType;
                colMapper.IsEnum         = prop.PropertyType.GetTypeInfo().IsEnum;
                colMapper.IsNullable     = Nullable.GetUnderlyingType(colMapper.MemberType) != null;
                if (colMapper.IsNullable)
                {
                    colMapper.UnderlyingType = Nullable.GetUnderlyingType(colMapper.MemberType);
                    colMapper.IsEnum         = colMapper.UnderlyingType.GetTypeInfo().IsEnum;
                }
                var toUnderlyingType = colMapper.UnderlyingType;
                var keyAttr          = prop.GetCustomAttribute <PrimaryKeyAttribute>();
                if (keyAttr != null)
                {
                    if (!String.IsNullOrEmpty(keyAttr.FieldName))
                    {
                        colMapper.FieldName = keyAttr.FieldName;
                    }
                    if (keyAttr.FieldType != null)
                    {
                        toUnderlyingType = keyAttr.FieldType;
                        colMapper.DbType = DbTypeMap.LookupDbType(keyAttr.FieldType);
                    }
                    colMapper.IsPrimaryKey    = true;
                    colMapper.IsAutoIncrement = keyAttr.AutoIncrement;
                    this.PrimaryKeys.Add(colMapper);
                }
                else
                {
                    colMapper.IsPrimaryKey = false;
                }
                var colAttr = prop.GetCustomAttribute <ColumnAttribute>();
                if (colAttr != null)
                {
                    if (!String.IsNullOrEmpty(colAttr.FieldName))
                    {
                        colMapper.FieldName = colAttr.FieldName;
                    }
                    if (colAttr.FieldType != null)
                    {
                        toUnderlyingType          = colAttr.FieldType;
                        colMapper.DbType          = DbTypeMap.LookupDbType(colAttr.FieldType);
                        colMapper.IsAutoIncrement = colAttr.AutoIncrement;
                    }
                }
                colMapper.IsString     = colMapper.UnderlyingType == typeof(string) || toUnderlyingType == typeof(string);
                colMapper.IsLinqBinary = colMapper.UnderlyingType.FullName == DbTypeMap.LinqBinary;
                this.MemberMappers.Add(prop.Name, colMapper);
            }
        }