示例#1
0
        /// <summary>
        /// 获取多对多的映射关系
        /// </summary>
        /// <param name="entityContext"></param>
        /// <param name="joinTable"></param>
        private void CreateManyToMany(EntityContext entityContext, TableSchema joinTable)
        {
            if (joinTable.ForeignKeys.Count != 2)
            {
                return;
            }

            var joinTableName  = joinTable.Name;
            var joinSchemaName = joinTable.Owner;

            // first fkey is always left, second fkey is right
            var leftForeignKey = joinTable.ForeignKeys[0];
            var leftTable      = leftForeignKey.PrimaryKeyTable;
            var joinLeftColumn = leftForeignKey.ForeignKeyMemberColumns.Select(c => c.Name).ToList();
            var leftEntity     = GetEntity(entityContext, leftTable, false, false);

            var rightForeignKey = joinTable.ForeignKeys[1];
            var rightTable      = rightForeignKey.PrimaryKeyTable;
            var joinRightColumn = rightForeignKey.ForeignKeyMemberColumns.Select(c => c.Name).ToList();
            var rightEntity     = GetEntity(entityContext, rightTable, false, false);

            string leftPropertyName = Settings.RelationshipName(rightEntity.ClassName);

            leftPropertyName = _namer.UniqueName(leftEntity.ClassName, leftPropertyName);

            string rightPropertyName = Settings.RelationshipName(leftEntity.ClassName);

            rightPropertyName = _namer.UniqueName(rightEntity.ClassName, rightPropertyName);

            string relationshipName = string.Format("{0}|{1}",
                                                    leftForeignKey.Name,
                                                    rightForeignKey.Name);

            relationshipName = _namer.UniqueRelationshipName(relationshipName);

            var left = new Relationship
            {
                RelationshipName  = relationshipName,
                IsForeignKey      = false,
                IsMapped          = true,
                ThisCardinality   = Cardinality.Many,
                ThisEntity        = leftEntity.ClassName,
                ThisPropertyName  = leftPropertyName,
                OtherCardinality  = Cardinality.Many,
                OtherEntity       = rightEntity.ClassName,
                OtherPropertyName = rightPropertyName,
                JoinTable         = joinTableName,
                JoinSchema        = joinSchemaName,
                JoinThisColumn    = new List <string>(joinLeftColumn),
                JoinOtherColumn   = new List <string>(joinRightColumn)
            };

            leftEntity.Relationships.Add(left);

            var right = new Relationship
            {
                RelationshipName  = relationshipName,
                IsForeignKey      = false,
                IsMapped          = false,
                ThisCardinality   = Cardinality.Many,
                ThisEntity        = rightEntity.ClassName,
                ThisPropertyName  = rightPropertyName,
                OtherCardinality  = Cardinality.Many,
                OtherEntity       = leftEntity.ClassName,
                OtherPropertyName = leftPropertyName,
                JoinTable         = joinTableName,
                JoinSchema        = joinSchemaName,
                JoinThisColumn    = new List <string>(joinRightColumn),
                JoinOtherColumn   = new List <string>(joinLeftColumn)
            };

            rightEntity.Relationships.Add(right);
        }
示例#2
0
        /// <summary>
        /// 创建数据库关系对应EF的Mapper
        /// </summary>
        /// <param name="entityContext">数据库上下文</param>
        /// <param name="foreignEntity">外键表对应实体</param>
        /// <param name="tableKeySchema">主键表</param>
        private void CreateRelationship(EntityContext entityContext, Entity foreignEntity, TableKeySchema tableKeySchema)
        {
            //获取主键表对应实体
            Entity primaryEntity = GetEntity(entityContext, tableKeySchema.PrimaryKeyTable, false, false);
            //主表类名
            string primaryName = primaryEntity.ClassName;
            //外键表名
            string foreignName = foreignEntity.ClassName;
            //映射名称
            string relationshipName = tableKeySchema.Name;

            //获取唯一映射名称
            relationshipName = _namer.UniqueRelationshipName(relationshipName);
            //判断是否级联删除
            bool isCascadeDelete = IsCascadeDelete(tableKeySchema);
            bool foreignMembersRequired;
            bool primaryMembersRequired;
            //获取外键表所有键属性名称
            List <string> foreignMembers = GetKeyMembers(foreignEntity, tableKeySchema.ForeignKeyMemberColumns, tableKeySchema.Name, out foreignMembersRequired);
            //获取主表中所有键的成员属性名称
            List <string> primaryMembers = GetKeyMembers(primaryEntity, tableKeySchema.PrimaryKeyMemberColumns, tableKeySchema.Name, out primaryMembersRequired);

            // 过滤没有外键主键的表处理
            if (foreignMembers == null || primaryMembers == null)
            {
                return;
            }
            Relationship foreignRelationship = foreignEntity.Relationships
                                               .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey);

            if (foreignRelationship == null)
            {
                foreignRelationship = new Relationship {
                    RelationshipName = relationshipName
                };
                foreignEntity.Relationships.Add(foreignRelationship);
            }
            foreignRelationship.IsMapped        = true;
            foreignRelationship.IsForeignKey    = true;
            foreignRelationship.ThisCardinality = foreignMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne;
            foreignRelationship.ThisEntity      = foreignName;
            foreignRelationship.ThisProperties  = new List <string>(foreignMembers);
            foreignRelationship.OtherEntity     = primaryName;
            foreignRelationship.OtherProperties = new List <string>(primaryMembers);
            foreignRelationship.CascadeDelete   = isCascadeDelete;

            string prefix = GetMemberPrefix(foreignRelationship, primaryName, foreignName);

            string foreignPropertyName = ToPropertyName(foreignEntity.ClassName, prefix + primaryName);

            foreignPropertyName = _namer.UniqueName(foreignEntity.ClassName, foreignPropertyName);
            foreignRelationship.ThisPropertyName = foreignPropertyName;

            // add reverse
            Relationship primaryRelationship = primaryEntity.Relationships
                                               .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey == false);

            if (primaryRelationship == null)
            {
                primaryRelationship = new Relationship {
                    RelationshipName = relationshipName
                };
                primaryEntity.Relationships.Add(primaryRelationship);
            }

            primaryRelationship.IsMapped        = false;
            primaryRelationship.IsForeignKey    = false;
            primaryRelationship.ThisEntity      = primaryName;
            primaryRelationship.ThisProperties  = new List <string>(primaryMembers);
            primaryRelationship.OtherEntity     = foreignName;
            primaryRelationship.OtherProperties = new List <string>(foreignMembers);
            primaryRelationship.CascadeDelete   = isCascadeDelete;

            bool isOneToOne = IsOneToOne(tableKeySchema, foreignRelationship);

            if (isOneToOne)
            {
                primaryRelationship.ThisCardinality = primaryMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne;
            }
            else
            {
                primaryRelationship.ThisCardinality = Cardinality.Many;
            }

            string primaryPropertyName = prefix + foreignName;

            if (!isOneToOne)
            {
                primaryPropertyName = Settings.RelationshipName(primaryPropertyName);
            }

            primaryPropertyName = ToPropertyName(primaryEntity.ClassName, primaryPropertyName);
            primaryPropertyName = _namer.UniqueName(primaryEntity.ClassName, primaryPropertyName);

            primaryRelationship.ThisPropertyName = primaryPropertyName;

            foreignRelationship.OtherPropertyName = primaryRelationship.ThisPropertyName;
            foreignRelationship.OtherCardinality  = primaryRelationship.ThisCardinality;

            primaryRelationship.OtherPropertyName = foreignRelationship.ThisPropertyName;
            primaryRelationship.OtherCardinality  = foreignRelationship.ThisCardinality;

            foreignRelationship.IsProcessed = true;
            primaryRelationship.IsProcessed = true;
        }
示例#3
0
        /// <summary>
        /// 创建数据库关系对应EF的Mapper
        /// </summary>
        /// <param name="entityContext">数据库上下文</param>
        /// <param name="foreignEntity">外键表对应实体</param>
        /// <param name="tableKeySchema">主键表</param>
        private void CreateRelationship(EntityContext entityContext, Entity foreignEntity, TableKeySchema tableKeySchema)
        {
            //获取主键表对应实体
            Entity primaryEntity = GetEntity(entityContext, tableKeySchema.PrimaryKeyTable, false, false);
            //主表类名
            string primaryName = primaryEntity.ClassName;
            //外键表名
            string foreignName = foreignEntity.ClassName;
            //映射名称
            string relationshipName = tableKeySchema.Name;
            //获取唯一映射名称
            relationshipName = _namer.UniqueRelationshipName(relationshipName);
            //判断是否级联删除
            bool isCascadeDelete = IsCascadeDelete(tableKeySchema);
            bool foreignMembersRequired;
            bool primaryMembersRequired;
            //获取外键表所有键属性名称
            List<string> foreignMembers = GetKeyMembers(foreignEntity, tableKeySchema.ForeignKeyMemberColumns, tableKeySchema.Name, out foreignMembersRequired);
            //获取主表中所有键的成员属性名称
            List<string> primaryMembers = GetKeyMembers(primaryEntity, tableKeySchema.PrimaryKeyMemberColumns, tableKeySchema.Name, out primaryMembersRequired);
            // 过滤没有外键主键的表处理
            if (foreignMembers == null || primaryMembers == null)
                return;
            Relationship foreignRelationship = foreignEntity.Relationships
              .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey);

            if (foreignRelationship == null)
            {
                foreignRelationship = new Relationship { RelationshipName = relationshipName };
                foreignEntity.Relationships.Add(foreignRelationship);
            }
            foreignRelationship.IsMapped = true;
            foreignRelationship.IsForeignKey = true;
            foreignRelationship.ThisCardinality = foreignMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne;
            foreignRelationship.ThisEntity = foreignName;
            foreignRelationship.ThisProperties = new List<string>(foreignMembers);
            foreignRelationship.OtherEntity = primaryName;
            foreignRelationship.OtherProperties = new List<string>(primaryMembers);
            foreignRelationship.CascadeDelete = isCascadeDelete;

            string prefix = GetMemberPrefix(foreignRelationship, primaryName, foreignName);

            string foreignPropertyName = ToPropertyName(foreignEntity.ClassName, prefix + primaryName);
            foreignPropertyName = _namer.UniqueName(foreignEntity.ClassName, foreignPropertyName);
            foreignRelationship.ThisPropertyName = foreignPropertyName;

            // add reverse
            Relationship primaryRelationship = primaryEntity.Relationships
              .FirstOrDefault(r => r.RelationshipName == relationshipName && r.IsForeignKey == false);

            if (primaryRelationship == null)
            {
                primaryRelationship = new Relationship { RelationshipName = relationshipName };
                primaryEntity.Relationships.Add(primaryRelationship);
            }

            primaryRelationship.IsMapped = false;
            primaryRelationship.IsForeignKey = false;
            primaryRelationship.ThisEntity = primaryName;
            primaryRelationship.ThisProperties = new List<string>(primaryMembers);
            primaryRelationship.OtherEntity = foreignName;
            primaryRelationship.OtherProperties = new List<string>(foreignMembers);
            primaryRelationship.CascadeDelete = isCascadeDelete;

            bool isOneToOne = IsOneToOne(tableKeySchema, foreignRelationship);
            if (isOneToOne)
                primaryRelationship.ThisCardinality = primaryMembersRequired ? Cardinality.One : Cardinality.ZeroOrOne;
            else
                primaryRelationship.ThisCardinality = Cardinality.Many;

            string primaryPropertyName = prefix + foreignName;
            if (!isOneToOne)
                primaryPropertyName = Settings.RelationshipName(primaryPropertyName);

            primaryPropertyName = ToPropertyName(primaryEntity.ClassName, primaryPropertyName);
            primaryPropertyName = _namer.UniqueName(primaryEntity.ClassName, primaryPropertyName);

            primaryRelationship.ThisPropertyName = primaryPropertyName;

            foreignRelationship.OtherPropertyName = primaryRelationship.ThisPropertyName;
            foreignRelationship.OtherCardinality = primaryRelationship.ThisCardinality;

            primaryRelationship.OtherPropertyName = foreignRelationship.ThisPropertyName;
            primaryRelationship.OtherCardinality = foreignRelationship.ThisCardinality;

            foreignRelationship.IsProcessed = true;
            primaryRelationship.IsProcessed = true;
        }
示例#4
0
        /// <summary>
        /// 获取多对多的映射关系
        /// </summary>
        /// <param name="entityContext"></param>
        /// <param name="joinTable"></param>
        private void CreateManyToMany(EntityContext entityContext, TableSchema joinTable)
        {
            if (joinTable.ForeignKeys.Count != 2)
                return;

            var joinTableName = joinTable.Name;
            var joinSchemaName = joinTable.Owner;

            // first fkey is always left, second fkey is right
            var leftForeignKey = joinTable.ForeignKeys[0];
            var leftTable = leftForeignKey.PrimaryKeyTable;
            var joinLeftColumn = leftForeignKey.ForeignKeyMemberColumns.Select(c => c.Name).ToList();
            var leftEntity = GetEntity(entityContext, leftTable, false, false);

            var rightForeignKey = joinTable.ForeignKeys[1];
            var rightTable = rightForeignKey.PrimaryKeyTable;
            var joinRightColumn = rightForeignKey.ForeignKeyMemberColumns.Select(c => c.Name).ToList();
            var rightEntity = GetEntity(entityContext, rightTable, false, false);

            string leftPropertyName = Settings.RelationshipName(rightEntity.ClassName);
            leftPropertyName = _namer.UniqueName(leftEntity.ClassName, leftPropertyName);

            string rightPropertyName = Settings.RelationshipName(leftEntity.ClassName);
            rightPropertyName = _namer.UniqueName(rightEntity.ClassName, rightPropertyName);

            string relationshipName = string.Format("{0}|{1}",
              leftForeignKey.Name,
              rightForeignKey.Name);

            relationshipName = _namer.UniqueRelationshipName(relationshipName);

            var left = new Relationship
            {
                RelationshipName = relationshipName,
                IsForeignKey = false,
                IsMapped = true,
                ThisCardinality = Cardinality.Many,
                ThisEntity = leftEntity.ClassName,
                ThisPropertyName = leftPropertyName,
                OtherCardinality = Cardinality.Many,
                OtherEntity = rightEntity.ClassName,
                OtherPropertyName = rightPropertyName,
                JoinTable = joinTableName,
                JoinSchema = joinSchemaName,
                JoinThisColumn = new List<string>(joinLeftColumn),
                JoinOtherColumn = new List<string>(joinRightColumn)
            };

            leftEntity.Relationships.Add(left);

            var right = new Relationship
            {
                RelationshipName = relationshipName,
                IsForeignKey = false,
                IsMapped = false,
                ThisCardinality = Cardinality.Many,
                ThisEntity = rightEntity.ClassName,
                ThisPropertyName = rightPropertyName,
                OtherCardinality = Cardinality.Many,
                OtherEntity = leftEntity.ClassName,
                OtherPropertyName = leftPropertyName,
                JoinTable = joinTableName,
                JoinSchema = joinSchemaName,
                JoinThisColumn = new List<string>(joinRightColumn),
                JoinOtherColumn = new List<string>(joinLeftColumn)
            };

            rightEntity.Relationships.Add(right);
        }
示例#5
0
        /// <summary>
        /// 判断一对一的关系
        /// </summary>
        /// <param name="tableKeySchema"></param>
        /// <param name="foreignRelationship"></param>
        /// <returns></returns>
        private static bool IsOneToOne(TableKeySchema tableKeySchema, Relationship foreignRelationship)
        {
            bool isFkeyPkey = tableKeySchema.ForeignKeyTable.HasPrimaryKey
                              && tableKeySchema.ForeignKeyTable.PrimaryKey != null
                              && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Count == 1
                              && tableKeySchema.ForeignKeyTable.PrimaryKey.MemberColumns.Contains(
                                foreignRelationship.ThisProperties.FirstOrDefault());

            if (isFkeyPkey)
                return true;

            return false;

            // if f.key is unique
            //return tableKeySchema.ForeignKeyMemberColumns.All(column => column.IsUnique);
        }
示例#6
0
        private static string GetMemberPrefix(Relationship relationship, string primaryClass, string foreignClass)
        {
            string thisKey = relationship.ThisProperties.FirstOrDefault() ?? string.Empty;
            string otherKey = relationship.OtherProperties.FirstOrDefault() ?? string.Empty;

            bool isSameName = thisKey.Equals(otherKey, StringComparison.OrdinalIgnoreCase);
            isSameName = (isSameName || thisKey.Equals(primaryClass + otherKey, StringComparison.OrdinalIgnoreCase));

            string prefix = string.Empty;
            if (isSameName)
                return prefix;

            prefix = thisKey.Replace(otherKey, "");
            prefix = prefix.Replace(primaryClass, "");
            prefix = prefix.Replace(foreignClass, "");
            prefix = Regex.Replace(prefix, @"(_ID|_id|_Id|\.ID|\.id|\.Id|ID|Id)$", "");
            prefix = Regex.Replace(prefix, @"^\d", "");

            return prefix;
        }