Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        // 获取成员包装器的外键特性
        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);
        }