Beispiel #1
0
        private static void UpdateRelationships(EntityContext generatedContext, Entity entity, ParsedEntity parsedEntity)
        {
            // sync relationships
            foreach (var parsedRelationship in parsedEntity.Relationships.Where(r => r.JoinTable == null))
            {
                var parsedProperties = parsedRelationship.ThisProperties;
                var relationship     = entity.Relationships
                                       .Where(r => !r.IsManyToMany)
                                       .FirstOrDefault(r => r.ThisProperties.Except(parsedProperties).Count() == 0);

                if (relationship == null)
                {
                    continue;
                }

                bool isThisSame  = relationship.ThisPropertyName == parsedRelationship.ThisPropertyName;
                bool isOtherSame = relationship.OtherPropertyName == parsedRelationship.OtherPropertyName;

                if (isThisSame && isOtherSame)
                {
                    continue;
                }

                if (!isThisSame)
                {
                    Debug.WriteLine("Rename Relationship Property '{0}.{1}' to '{0}.{2}'.",
                                    relationship.ThisEntity,
                                    relationship.ThisPropertyName,
                                    parsedRelationship.ThisPropertyName);

                    relationship.ThisPropertyName = parsedRelationship.ThisPropertyName;
                }
                if (!isOtherSame)
                {
                    Debug.WriteLine("Rename Relationship Property '{0}.{1}' to '{0}.{2}'.",
                                    relationship.OtherEntity,
                                    relationship.OtherPropertyName,
                                    parsedRelationship.OtherPropertyName);

                    relationship.OtherPropertyName = parsedRelationship.OtherPropertyName;
                }

                // sync other relationship
                var otherEntity = generatedContext.Entities.ByClass(relationship.OtherEntity);
                if (otherEntity == null)
                {
                    continue;
                }

                var otherRelationship = otherEntity.Relationships.ByName(relationship.RelationshipName);
                if (otherRelationship == null)
                {
                    continue;
                }

                otherRelationship.ThisPropertyName  = relationship.OtherPropertyName;
                otherRelationship.OtherPropertyName = relationship.ThisPropertyName;
            }

            // sync many to many
            foreach (var parsedRelationship in parsedEntity.Relationships.Where(r => r.JoinTable != null))
            {
                var joinThisColumn  = parsedRelationship.JoinThisColumn;
                var joinOtherColumn = parsedRelationship.JoinOtherColumn;

                var relationship = entity.Relationships
                                   .Where(r => r.IsManyToMany)
                                   .FirstOrDefault(r =>
                                                   r.JoinThisColumn.Except(joinThisColumn).Count() == 0 &&
                                                   r.JoinOtherColumn.Except(joinOtherColumn).Count() == 0 &&
                                                   r.JoinTable == parsedRelationship.JoinTable &&
                                                   r.JoinSchema == parsedRelationship.JoinSchema);

                if (relationship == null)
                {
                    continue;
                }


                bool isThisSame  = relationship.ThisPropertyName == parsedRelationship.ThisPropertyName;
                bool isOtherSame = relationship.OtherPropertyName == parsedRelationship.OtherPropertyName;

                if (isThisSame && isOtherSame)
                {
                    continue;
                }

                if (!isThisSame)
                {
                    Debug.WriteLine("Rename Relationship Property '{0}.{1}' to '{0}.{2}'.",
                                    relationship.ThisEntity,
                                    relationship.ThisPropertyName,
                                    parsedRelationship.ThisPropertyName);

                    relationship.ThisPropertyName = parsedRelationship.ThisPropertyName;
                }
                if (!isOtherSame)
                {
                    Debug.WriteLine("Rename Relationship Property '{0}.{1}' to '{0}.{2}'.",
                                    relationship.OtherEntity,
                                    relationship.OtherPropertyName,
                                    parsedRelationship.OtherPropertyName);

                    relationship.OtherPropertyName = parsedRelationship.OtherPropertyName;
                }

                // sync other relationship
                var otherEntity = generatedContext.Entities.ByClass(relationship.OtherEntity);
                if (otherEntity == null)
                {
                    continue;
                }

                var otherRelationship = otherEntity.Relationships.ByName(relationship.RelationshipName);
                if (otherRelationship == null)
                {
                    continue;
                }

                otherRelationship.ThisPropertyName  = relationship.OtherPropertyName;
                otherRelationship.OtherPropertyName = relationship.ThisPropertyName;
            }
        }
Beispiel #2
0
        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
            };

            left.IsForeignKey = false;
            left.IsMapped     = true;

            left.ThisCardinality  = Cardinality.Many;
            left.ThisEntity       = leftEntity.ClassName;
            left.ThisPropertyName = leftPropertyName;

            left.OtherCardinality  = Cardinality.Many;
            left.OtherEntity       = rightEntity.ClassName;
            left.OtherPropertyName = rightPropertyName;

            left.JoinTable       = joinTableName;
            left.JoinSchema      = joinSchemaName;
            left.JoinThisColumn  = new List <string>(joinLeftColumn);
            left.JoinOtherColumn = new List <string>(joinRightColumn);

            leftEntity.Relationships.Add(left);

            var right = new Relationship {
                RelationshipName = relationshipName
            };

            right.IsForeignKey = false;
            right.IsMapped     = false;

            right.ThisCardinality  = Cardinality.Many;
            right.ThisEntity       = rightEntity.ClassName;
            right.ThisPropertyName = rightPropertyName;

            right.OtherCardinality  = Cardinality.Many;
            right.OtherEntity       = leftEntity.ClassName;
            right.OtherPropertyName = leftPropertyName;

            right.JoinTable       = joinTableName;
            right.JoinSchema      = joinSchemaName;
            right.JoinThisColumn  = new List <string>(joinRightColumn);
            right.JoinOtherColumn = new List <string>(joinLeftColumn);

            rightEntity.Relationships.Add(right);
        }
Beispiel #3
0
        private static void UpdateFromMapping(EntityContext generatedContext, string mappingDirectory)
        {
            if (generatedContext == null ||
                mappingDirectory == null ||
                !Directory.Exists(mappingDirectory))
            {
                return;
            }

            // parse all mapping files
            var mappingFiles   = Directory.EnumerateFiles(mappingDirectory, "*.Generated.cs");
            var parsedEntities = mappingFiles
                                 .Select(MappingParser.Parse)
                                 .Where(parsedEntity => parsedEntity != null)
                                 .ToList();

            var relationshipQueue = new List <Tuple <Entity, ParsedEntity> >();

            // update all entity and property names first because relationships are linked by property names
            foreach (var parsedEntity in parsedEntities)
            {
                // find entity by table name to support renaming entity
                var entity = generatedContext.Entities
                             .ByTable(parsedEntity.TableName, parsedEntity.TableSchema);

                if (entity == null)
                {
                    continue;
                }

                // sync names
                if (entity.MappingName != parsedEntity.MappingClass)
                {
                    Debug.WriteLine("Rename Mapping Class'{0}' to '{1}'.",
                                    entity.MappingName,
                                    parsedEntity.MappingClass);

                    entity.MappingName = parsedEntity.MappingClass;
                }

                // use rename api to make sure all instances are renamed
                generatedContext.RenameEntity(entity.ClassName, parsedEntity.EntityClass);

                // sync properties
                foreach (var parsedProperty in parsedEntity.Properties)
                {
                    // find property by column name to support property name rename
                    var property = entity.Properties.ByColumn(parsedProperty.ColumnName);
                    if (property == null)
                    {
                        continue;
                    }

                    // use rename api to make sure all instances are renamed
                    generatedContext.RenameProperty(
                        entity.ClassName,
                        property.PropertyName,
                        parsedProperty.PropertyName);
                }

                // save relationship for later processing
                var item = new Tuple <Entity, ParsedEntity>(entity, parsedEntity);
                relationshipQueue.Add(item);
            }

            // update relationships last
            foreach (var tuple in relationshipQueue)
            {
                UpdateRelationships(generatedContext, tuple.Item1, tuple.Item2);
            }
        }
Beispiel #4
0
        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;

            var foreignMembers = GetKeyMembers(foreignEntity, tableKeySchema.ForeignKeyMemberColumns, tableKeySchema.Name, out foreignMembersRequired);
            var primaryMembers = GetKeyMembers(primaryEntity, tableKeySchema.PrimaryKeyMemberColumns, tableKeySchema.Name, out primaryMembersRequired);

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