Esempio n. 1
0
 public void Add <T>(string key, T value, DbNetParamterDirection direction, int sourceIndex, SourceType sourceType, CacheKeyType cacheKeyType)
 {
     if (dic.ContainsKey(key))
     {
         throw new Exception(string.Format("参数名称重复,来自 参数位置:{0} 源:{1}", sourceIndex, sourceType == SourceType.FromClass?"来自类属性":
                                           sourceType == SourceType.FromArg ? "来自方法参数":"未知"));
     }
     dic.Add(key, new DbNetParamter {
         Name = key, Value = value, Direction = direction, SourceIndex = sourceIndex, SourceType = sourceType, CacheKeyType = cacheKeyType
     });
 }
Esempio n. 2
0
        /// <summary>
        /// 获取参数封装入集合
        /// </summary>
        /// <param name="paramterList"></param>
        /// <param name="gen"></param>
        /// <param name="paramterListBulider"></param>
        private static void GetParamters(List <Tuple <string, int, MethodInfo, Type> > outputParamters,
                                         ParameterInfo[] paramterList, ILGenerator gen, LocalBuilder paramterListBulider, bool use_cache, string sqlTextKey, out ParameterInfo scope_parameterInfo)
        {
            scope_parameterInfo = null;
            bool haschache_attr = paramterList.Any(x => x.GetCustomAttribute <DbCacheKeyAttribute>() != null);

            foreach (var paramter in paramterList)
            {
                if (!string.IsNullOrEmpty(sqlTextKey) && paramter.Name == sqlTextKey)
                {
                    //跳过指定sql语句的参数
                    continue;
                }
                Type pType = paramter.ParameterType;
                Type eType = pType.GetElementType();//若为ref或out参数则eType为其原来类型
                if (pType.GetInterface(SCOPE_ITEM) != null ||
                    (eType != null && eType.GetInterface(SCOPE_ITEM) != null))
                {
                    //IDbNetScope类型为事务处理变量,不能添加到参数中
                    scope_parameterInfo = paramter;
                    continue;
                }
                LocalBuilder           pTypeBulider = null;
                DbNetParamterDirection dir          = DbNetParamterDirection.Input;
                CacheKeyType           cacheKeyType = CacheKeyType.None;
                if (use_cache)
                {
                    cacheKeyType = CacheKeyType.Bind;
                    if (haschache_attr)
                    {
                        cacheKeyType = CacheKeyType.None;
                    }
                    var cache_attr = paramter.GetCustomAttribute <DbCacheKeyAttribute>();
                    if (cache_attr != null)
                    {
                        cacheKeyType = CacheKeyType.Bind;
                    }
                }
                if (!paramter.IsOut &&
                    !pType.IsByRef)
                {
                    pTypeBulider = gen.DeclareLocal(pType);
                    gen.Emit(OpCodes.Ldarg, paramter.Position + 1);
                }
                else
                {
                    dir          = DbNetParamterDirection.InputAndOutPut;
                    pTypeBulider = gen.DeclareLocal(eType);
                    if (pType.IsByRef)
                    {
                        //获取ref参数的值
                        gen.Emit(OpCodes.Ldarg, paramter.Position + 1);
                        GetRef(gen, pTypeBulider.LocalType);
                    }
                }
                gen.Emit(OpCodes.Stloc, pTypeBulider);
                if (pTypeBulider.LocalType.IsClass)
                {
                    Label isNullLabel = gen.DefineLabel();
                    gen.Emit(OpCodes.Ldloc, pTypeBulider);
                    gen.Emit(OpCodes.Ldnull);
                    gen.Emit(OpCodes.Ceq);
                    gen.Emit(OpCodes.Brfalse, isNullLabel);
                    gen.Emit(OpCodes.Call, MethodHelper.defaultMethod.MakeGenericMethod(pTypeBulider.LocalType));
                    gen.Emit(OpCodes.Stloc, pTypeBulider);
                    gen.MarkLabel(isNullLabel);
                }
                if (paramter.IsOut || pType.IsByRef)
                {
                    //输出参数获取下阶段备用
                    outputParamters.Add(new Tuple <string, int, MethodInfo, Type>(paramter.Name, paramter.Position + 1, null, eType));
                }
                if (pTypeBulider.LocalType == typeof(string) ||
                    pTypeBulider.LocalType.IsValueType ||
                    pTypeBulider.LocalType.IsArray)
                {
                    //添加结构体或者string到集合
                    gen.Emit(OpCodes.Ldloc, paramterListBulider);
                    gen.Emit(OpCodes.Ldstr, paramter.Name);
                    gen.Emit(OpCodes.Ldloc, pTypeBulider);
                    gen.Emit(OpCodes.Ldc_I4, (int)dir);
                    gen.Emit(OpCodes.Ldc_I4, paramter.Position);
                    gen.Emit(OpCodes.Ldc_I4, (int)SourceType.FromArg);
                    gen.Emit(OpCodes.Ldc_I4, (int)cacheKeyType);
                    gen.Emit(OpCodes.Call, MethodHelper.paramterMethod.MakeGenericMethod(pTypeBulider.LocalType));
                }
                else
                {
                    //如果参数是类则需进一步处理
                    var pinfo        = pTypeBulider.LocalType.GetProperties();
                    var cache_attr_c = paramter.GetCustomAttribute <DbCacheKeyAttribute>();
                    foreach (var p in pinfo)
                    {
                        DbParamterAttribute attr_p = p.GetCustomAttribute <DbParamterAttribute>(true);
                        bool   except = false;
                        string name   = string.Empty;
                        DbNetParamterDirection pdir           = DbNetParamterDirection.Input;
                        CacheKeyType           p_cacheKeyType = CacheKeyType.None;
                        if (use_cache)
                        {
                            p_cacheKeyType = CacheKeyType.Bind;
                            if (haschache_attr)
                            {
                                p_cacheKeyType = CacheKeyType.None;
                            }
                            if (cache_attr_c != null)
                            {
                                p_cacheKeyType = CacheKeyType.Bind;
                            }
                            if (attr_p != null && attr_p.CacheKey != CacheKeyType.Default)
                            {
                                p_cacheKeyType = attr_p.CacheKey;
                            }
                        }
                        if (paramter.IsOut)
                        {
                            //输出参数获取下阶段备用
                            outputParamters.Add(new Tuple <string, int, MethodInfo, Type>(paramter.Name, paramter.Position + 1, p.GetSetMethod(), p.PropertyType));
                            pdir = DbNetParamterDirection.Output;
                        }
                        else if (pType.IsByRef)
                        {
                            //输出参数获取下阶段备用
                            outputParamters.Add(new Tuple <string, int, MethodInfo, Type>(paramter.Name, paramter.Position + 1, p.GetSetMethod(), p.PropertyType));
                            pdir = DbNetParamterDirection.InputAndOutPut;
                        }
                        if (attr_p != null)
                        {
                            except = attr_p.Except;
                            name   = attr_p.Name;
                            pdir   = attr_p.ParameterDirection;
                        }
                        if (string.IsNullOrEmpty(name))
                        {
                            name = p.Name;
                        }
                        if (!except)
                        {
                            gen.Emit(OpCodes.Ldloc, paramterListBulider);
                            gen.Emit(OpCodes.Ldstr, name);
                            gen.Emit(OpCodes.Ldloc, pTypeBulider);
                            gen.Emit(OpCodes.Call, p.GetGetMethod());
                            gen.Emit(OpCodes.Ldc_I4, (int)pdir);
                            gen.Emit(OpCodes.Ldc_I4, paramter.Position);
                            gen.Emit(OpCodes.Ldc_I4, (int)SourceType.FromClass);
                            gen.Emit(OpCodes.Ldc_I4, (int)p_cacheKeyType);
                            gen.Emit(OpCodes.Call, MethodHelper.paramterMethod.MakeGenericMethod(p.PropertyType));
                        }
                    }
                }
            }
        }