/// <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); }
// 获取成员包装器的外键特性 private ForeignKeyAttribute GetForeignKeyAttribute(FieldAccessorBase m, string memberName) { if (m == null) { throw new XFrameworkException("Member {0}.{1} not found.", _type.Name, memberName); } var attribute = m.GetCustomAttribute <ForeignKeyAttribute>(); if (attribute == null) { // 如果是属性,要求标记为 virtual var property = m as PropertyAccessor; if (property != null) { var getMethod = property.Member.GetGetMethod(true); if (getMethod != null && !getMethod.IsVirtual) { return(null); } } // 区分一对一和一对多导航属性 var navEntityType = m.CLRType.IsGenericType ? m.CLRType.GetGenericArguments()[0] : m.CLRType; var navTypeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(navEntityType); if (TypeUtils.IsCollectionType(m.CLRType)) { // 1:n 关系,外键实体必须持有当前实体的所有主键属性 int index = 0; string[] innerKeys = null; string[] outerKeys = null; foreach (FieldAccessorBase inner in this.KeyMembers) { if (!navTypeRuntime.Members.Contains(inner.Name)) { innerKeys = null; outerKeys = null; break; } else { var outer = navTypeRuntime.GetMember <FieldAccessorBase>(inner.Name); if (outer == null) { innerKeys = null; outerKeys = null; break; } else { if (innerKeys == null) { innerKeys = new string[this.KeyMembers.Count]; } if (outerKeys == null) { outerKeys = new string[this.KeyMembers.Count]; } innerKeys[index] = inner.Column != null && !string.IsNullOrEmpty(inner.Column.Name) ? inner.Column.Name : inner.Name; outerKeys[index] = inner.Column != null && !string.IsNullOrEmpty(inner.Column.Name) ? inner.Column.Name : inner.Name; } } index += 1; } if (innerKeys != null) { attribute = new ForeignKeyAttribute(innerKeys, outerKeys); } } else { // 1:1 关系,分两种情况 // 1. 当前实体持有外键实体的主键属性 // 2. 外键实体持有当前实体的主键属性 if (navTypeRuntime.KeyMembers.Count > 0) { int index = 0; string[] innerKeys = null; string[] outerKeys = null; foreach (FieldAccessorBase outer in navTypeRuntime.KeyMembers) { if (!this.Members.Contains(outer.Name)) { innerKeys = null; outerKeys = null; break; } else { var inner = this.GetMember <FieldAccessorBase>(outer.Name); if (inner == null) { innerKeys = null; outerKeys = null; break; } else { if (innerKeys == null) { innerKeys = new string[navTypeRuntime.KeyMembers.Count]; } if (outerKeys == null) { outerKeys = new string[navTypeRuntime.KeyMembers.Count]; } innerKeys[index] = inner.Column != null && !string.IsNullOrEmpty(inner.Column.Name) ? inner.Column.Name : inner.Name; outerKeys[index] = outer.Column != null && !string.IsNullOrEmpty(outer.Column.Name) ? outer.Column.Name : outer.Name; } } index += 1; } if (innerKeys != null) { attribute = new ForeignKeyAttribute(innerKeys, outerKeys); } } if (attribute == null) { int index = 0; string[] innerKeys = null; string[] outerKeys = null; foreach (FieldAccessorBase inner in this.KeyMembers) { if (!navTypeRuntime.Members.Contains(inner.Name)) { innerKeys = null; outerKeys = null; break; } else { var outer = navTypeRuntime.GetMember <FieldAccessorBase>(inner.Name); if (outer == null) { innerKeys = null; outerKeys = null; break; } else { if (innerKeys == null) { innerKeys = new string[this.KeyMembers.Count]; } if (outerKeys == null) { outerKeys = new string[this.KeyMembers.Count]; } innerKeys[index] = inner.Column != null && !string.IsNullOrEmpty(inner.Column.Name) ? inner.Column.Name : inner.Name; outerKeys[index] = inner.Column != null && !string.IsNullOrEmpty(inner.Column.Name) ? inner.Column.Name : inner.Name; } } index += 1; } if (innerKeys != null) { attribute = new ForeignKeyAttribute(innerKeys, outerKeys); } } } } return(attribute); }