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