/// <summary> /// 获取成员反射器 /// </summary> /// <param name="memberName">成员名称</param> /// <returns></returns> public T GetMember <T>(string memberName) where T : MemberAccessorBase { MemberAccessorBase m = null; this.Members.TryGetValue(memberName, out m); return(m as T); }
/// <summary> /// 访问表示方法调用的节点 /// </summary> /// <param name="node">方法调用节点</param> /// <returns></returns> protected Expression VisitMethodCall(BinaryExpression node) { string methodName = string.Empty; if (node.NodeType == ExpressionType.Modulo) { methodName = "Modulo"; } else if (node.NodeType == ExpressionType.Divide) { methodName = "Divide"; } else { methodName = node.Method.Name; } MemberAccessorBase m = this.TypeRuntime.GetMethod("Visit" + methodName, new[] { typeof(BinaryExpression) }); if (m == null) { throw new XFrameworkException("{0}.{1} is not supported.", node.Method.DeclaringType, node.Method.Name); } else { object exp = m.Invoke(this, new object[] { node }); return(exp as Expression); } }
/// <summary> /// 访问成员 /// </summary> /// <param name="target">实例</param> /// <param name="memberName">成员名称</param> /// <param name="parameters">参数列表</param> /// <returns></returns> public object Invoke(object target, string memberName, params object[] parameters) { MemberAccessorBase m = null; this.Members.TryGetValue(memberName, out m); if (m == null) { throw new XFrameworkException("{0}.{1} Not Found.", _type.Name, memberName); } return(m.Invoke(target, parameters)); }
/// <summary> /// 获取成员包装器的自定义特性。 /// </summary> /// <typeparam name="TAttribute">自定义特性</typeparam> /// <returns></returns> public TAttribute GetMemberAttribute <TAttribute>(string memberName) where TAttribute : Attribute { MemberAccessorBase m = this.GetMember(memberName); if (typeof(TAttribute) == typeof(ForeignKeyAttribute)) { return((TAttribute)(object)this.GetForeignKeyAttribute(m as FieldAccessorBase, memberName)); } else { return(m != null?m.GetCustomAttribute <TAttribute>() : null); } }
/// <summary> /// 获取成员反射器 /// </summary> /// <param name="memberName">成员名称</param> /// <returns></returns> public MemberAccessorBase GetMember(string memberName) { MemberAccessorBase m = null; this.Members.TryGetValue(memberName, out m); if (m != null) { // 有多个相同名称的方法成员(重载) var method = m as MethodAccessor; if (method != null && method.Overrides != null && method.Overrides.Count > 0) { throw new XFrameworkException("{0}.{1} member has another overrides,please use TypeRuntimeInfo.GetMethod method.", _type.Name, memberName); } } return(m); }
/// <summary> /// 访问表示方法调用的节点 /// </summary> /// <param name="node">方法调用节点</param> /// <returns></returns> protected Expression VisitMethodCall(MethodCallExpression node) { MemberAccessorBase m = null; if (node.Method.Name == "Concat") { m = this.TypeRuntime.GetMethod("Visit" + node.Method.Name, new[] { typeof(MethodCallExpression) }); } else { m = this.TypeRuntime.GetMember("Visit" + node.Method.Name); } if (m == null) { throw new XFrameworkException("{0}.{1} is not supported.", node.Method.DeclaringType, node.Method.Name); } else { object exp = m.Invoke(this, new object[] { node }); return(exp as Expression); } }
/// <summary> /// 创建成员反射器 /// </summary> /// <param name="member">元数据</param> /// <returns></returns> public static MemberAccessorBase Create(MemberInfo member) { MemberAccessorBase m = null; if (member.MemberType == MemberTypes.Property) { m = new PropertyAccessor((PropertyInfo)member); } else if (member.MemberType == MemberTypes.Field) { m = new FieldAccessor((FieldInfo)member); } else if (member.MemberType == MemberTypes.Method) { m = new MethodAccessor((MethodInfo)member); } if (m == null) { throw new XFrameworkException("{0}.{1} not supported", member.ReflectedType, member.Name); } return(m); }
/// <summary> /// 初始化成员集合 /// </summary> /// <param name="type"></param> /// <returns></returns> protected virtual MemberAccessorCollection Initialize(Type type) { // Fix issue#多线程下导致 FieldCount 不正确 // 单个实例只初始化一次 //Fixed issue#匿名类的属性不可写 //匿名类:new{ClientId=a.ClientId} if (!_isInitialize) { lock (_lock) { if (!_isInitialize) { var members = new MemberAccessorCollection(); var navMembers = new MemberAccessorCollection(); var keyMembers = new MemberAccessorCollection(); FieldAccessorBase identityMember = null; var sources = this.GetTypeMembers(type, _includePrivates).Select(a => MemberAccessorBase.Create(a)); foreach (var m in sources) { if (m.GetCustomAttribute <System.Runtime.CompilerServices.CompilerGeneratedAttribute>() != null) { continue; } // 添加成员 members.Add(m); var field = m as FieldAccessorBase; if (field != null) { if (field.IsKey) { keyMembers.Add(field); } if (field.IsIdentity) { identityMember = field; } if (field.IsNavigation) { navMembers.Add(field); } } } _members = members; _navMembers = navMembers; _keyMembers = keyMembers; _identityMember = identityMember; _isInitialize = true; } } } return(_members); }
// 反序列化导航属性 // @prevLine 前一行数据 // @isLine 是否同一行数据<同一父级> void Deserialize_Navigation(object prevModel, object model, string typeName, bool isThisLine) { // CRM_SaleOrder.Client // CRM_SaleOrder.Client.AccountList Type type = model.GetType(); TypeRuntimeInfo typeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(type); if (string.IsNullOrEmpty(typeName)) { typeName = type.Name; } //foreach (var kvp in _map.Navigations) foreach (var navigation in _map.SelectedNavs) { int start = -1; int end = -1; if (navigation.FieldCount > 0) { start = navigation.StartIndex; end = navigation.StartIndex + navigation.FieldCount; } string keyName = typeName + "." + navigation.Name; if (keyName != navigation.Key) { continue; } var navMember = typeRuntime.GetMember <FieldAccessorBase>(navigation.Name); if (navMember == null) { continue; } Type navType = navMember.CLRType; Func <IDataRecord, object> deserializer = null; TypeRuntimeInfo navTypeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(navType); object navCollection = null; if (TypeUtils.IsCollectionType(navType)) { // 1:n关系,导航属性为 List<T> navCollection = navMember.Invoke(model); if (navCollection == null) { // new 一个列表类型,如果导航属性定义为接口,则默认使用List<T>来实例化 TypeRuntimeInfo navTypeRuntime2 = navType.IsInterface ? TypeRuntimeInfoCache.GetRuntimeInfo(typeof(List <>).MakeGenericType(navTypeRuntime.GenericArguments[0])) : navTypeRuntime; navCollection = navTypeRuntime2.Constructor.Invoke(); navMember.Invoke(model, navCollection); } } if (!_deserializers.TryGetValue(keyName, out deserializer)) { deserializer = _deserializerImpl.GetTypeDeserializer(navType.IsGenericType ? navTypeRuntime.GenericArguments[0] : navType, _reader, _map.SelectedColumns, start, end); _deserializers[keyName] = deserializer; } // 如果整个导航链中某一个导航属性为空,则跳出递归 object navModel = deserializer(_reader); if (navModel != null) { if (navCollection == null) { // 非集合型导航属性 navMember.Invoke(model, navModel); // // // } else { // 集合型导航属性 if (prevModel != null && isThisLine) { #region 合并列表 // 判断如果属于同一个主表,则合并到上一行的当前明细列表 // 例:CRM_SaleOrder.Client.AccountList string[] keys = keyName.Split('.'); TypeRuntimeInfo curTypeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(_entityType); Type curType = curTypeRuntime.Type; MemberAccessorBase curAccessor = null; object curModel = prevModel; for (int i = 1; i < keys.Length; i++) { curAccessor = curTypeRuntime.GetMember(keys[i]); curModel = curAccessor.Invoke(curModel); if (curModel == null) { continue; } curType = curModel.GetType(); curTypeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(curType); // <<<<<<<<<<< 一对多对多关系 >>>>>>>>>> if (curType.IsGenericType && i != keys.Length - 1) { curTypeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(curType); //if (curTypeRuntime.GenericTypeDefinition == typeof(List<>)) if (TypeUtils.IsCollectionType(curType)) { var member_Count = curTypeRuntime.GetMember("get_Count"); int count = Convert.ToInt32(member_Count.Invoke(curModel)); // List.Count if (count > 0) { var member_Index = curTypeRuntime.GetMember("get_Item"); curModel = member_Index.Invoke(curModel, count - 1); // List[List.Count-1] curTypeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(curModel.GetType()); } else { // user.Roles.RoleFuncs=>Roles 列表有可能为空 curModel = null; break; } } } } if (curModel != null) { // 如果有两个以上的一对多关系的导航属性,那么在加入列表之前就需要剔除重复的实体 bool isAny = false; if (_map.SelectedNavs.Count > 1) { if (_manyNavigationNumber == null) { _manyNavigationNumber = _map.SelectedNavs.Count(x => HasMany(x.Member)); } if (_manyNavigationNumber != null && _manyNavigationNumber.Value > 1) { if (!_manyNavigationKeys.ContainsKey(keyName)) { _manyNavigationKeys[keyName] = new HashSet <string>(); } curTypeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(navModel.GetType()); StringBuilder keyBuilder = new StringBuilder(64); foreach (var m in curTypeRuntime.KeyMembers) { var value = m.Invoke(navModel); keyBuilder.AppendFormat("{0}={1};", m.Name, (value ?? string.Empty).ToString()); } string hash = keyBuilder.ToString(); if (_manyNavigationKeys[keyName].Contains(hash)) { isAny = true; } else { _manyNavigationKeys[keyName].Add(hash); } } } if (!isAny) { // 如果列表中不存在,则添加到上一行的相同导航列表中去 var member_Add = navTypeRuntime.GetMember("Add"); member_Add.Invoke(curModel, navModel); } } #endregion } else { // 此时的 navTypeRuntime 是 List<> 类型的运行时 // 先添加 List 列表 var member_Add = navTypeRuntime.GetMember("Add"); member_Add.Invoke(navCollection, navModel); var curTypeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(navModel.GetType()); StringBuilder keyBuilder = new StringBuilder(64); foreach (var m in curTypeRuntime.KeyMembers) { var value = m.Invoke(navModel); keyBuilder.AppendFormat("{0}={1};", m.Name, (value ?? string.Empty).ToString()); } string hash = keyBuilder.ToString(); if (!_manyNavigationKeys.ContainsKey(keyName)) { _manyNavigationKeys[keyName] = new HashSet <string>(); } if (!_manyNavigationKeys[keyName].Contains(hash)) { _manyNavigationKeys[keyName].Add(hash); } } } if (TypeUtils.IsCollectionType(navTypeRuntime.Type)) { navTypeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(navTypeRuntime.GenericArguments[0]); } if (navTypeRuntime.NavMembers.Count > 0) { Deserialize_Navigation(prevModel, navModel, keyName, isThisLine); } } } }