示例#1
0
        private static void CreateParamter(ILGenerator il, string paramPrefix, MemberMapper colMapper, bool isTyped)
        {
            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.MemberName);
            il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.ParameterName)).GetSetMethod(), null);
            // stack is now [parameters][parameters][parameter]

            // stack is now [parameters][parameters][parameter][parameter].DbType={DbType}
            il.Emit(OpCodes.Dup);
            LoadInt32(il, (int)colMapper.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);

            il.Emit(OpCodes.Dup);
            if (isTyped)
            {
                il.Emit(OpCodes.Ldarg_1);
            }
            else
            {
                il.Emit(OpCodes.Ldloc_0);
            }

            il.Emit(OpCodes.Callvirt, colMapper.GetMethodInfo);
            // stack is now [parameters][parameters][parameter][parameter][value]
            if (colMapper.IsValueType)
            {
                il.Emit(OpCodes.Box, colMapper.MemberType);
                if (colMapper.IsEnum && colMapper.IsString)
                {
                    // stack is now [parameters][parameters][parameter][parameter][int-value][enum-type]
                    il.Emit(OpCodes.Ldtoken, colMapper.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 (colMapper.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);
                if (colMapper.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);

                    il.DeclareLocal(typeof(int));
                    if (isTyped)
                    {
                        il.Emit(OpCodes.Stloc_0);
                    }
                    else
                    {
                        il.Emit(OpCodes.Stloc_1);
                    }
                }
                if (colMapper.IsLinqBinary)
                {
                    il.EmitCall(OpCodes.Callvirt, colMapper.MemberType.GetMethod("ToArray", BindingFlags.Public | BindingFlags.Instance), null);
                    // stack is now [parameters][parameters][parameter][parameter][bytesArray]
                }
                il.EmitCall(OpCodes.Callvirt, typeof(IDataParameter).GetProperty(nameof(IDataParameter.Value)).GetSetMethod(), null);

                // stack is now [parameters][parameters][parameter]
                if (colMapper.IsString)
                {
                    il.Emit(OpCodes.Dup);
                    // stack is now [parameters][parameters][parameter][parameter].Size=len(string)
                    if (isTyped)
                    {
                        il.Emit(OpCodes.Ldloc_0);
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldloc_1);
                    }
                    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]
        }
示例#2
0
 private static string GetAliasParameterSql(IOrmProvider provider, MemberMapper colMapper)
 {
     return(provider.GetColumnName(colMapper.FieldName) + " AS " + provider.GetPropertyName(colMapper.MemberName));
 }
示例#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);
            }
        }
示例#4
0
 private static string GetSetParameterSql(IOrmProvider provider, MemberMapper colMapper)
 {
     return(provider.GetColumnName(colMapper.FieldName) + "=" + provider.ParamPrefix + colMapper.MemberName);
 }