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 }); }
/// <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)); } } } } }