private void ResolveRelations() { //Transform all relations according to type List <Relation> resolvedRelations = new List <Relation>(); foreach (var item in Relations.GroupBy(s => s.Grouping)) { //in case of count 1 it is simple if (item.Count() == 1) { resolvedRelations.Add(item.First().Clone() as Relation); } //If all directed the same way generate separate relations else if (item.Count() == item.Where(s => s.Table == item.First().Table).Count()) { foreach (Relation relation in item) { resolvedRelations.Add(relation.Clone() as Relation); } } //if two opposite relations handle as one composite else if (item.Count() == 2) { //Two one to many = one many to many if (item.Where(s => s.Type == RelationshipType.OneToMany).Count() == 2) { Relation manyToMany = item.First().Clone() as Relation; manyToMany.Type = RelationshipType.ManyToMany; manyToMany.Name = item.First().Name + "_" + item.Last().Name; resolvedRelations.Add(manyToMany); } //Two one one = one one one; else if (item.Where(s => s.Type == RelationshipType.OneToOne).Count() == 2) { resolvedRelations.Add(item.First().Clone() as Relation); } //else use the one to many relation else { Relation relation = (Relation)item.First().Clone(); relation.Type = RelationshipType.OneToMany; resolvedRelations.Add(relation); } } //generate separate else { foreach (Relation relation in item) { resolvedRelations.Add(relation.Clone() as Relation); } } } //Now go through all relations and generate FKs and Tables foreach (Relation resolved in resolvedRelations) { ColumnDefinition definition; switch (resolved.Type) { case RelationshipType.OneToOne: definition = ColumnDefinition.CreateColumnDefinition(null, Engine.instance.Settings.FkPrefix + resolved.Name, resolved.Table.Index, KeyType.Foreign, resolved.ForeignTable.Index); definition = ColumnDefinition.InsertColumnDefinition(definition, Constraints); definition = ColumnDefinition.InsertColumnDefinition(definition.CleanForeignKey(), ColumnDefinitions); break; case RelationshipType.OneToMany: definition = ColumnDefinition.CreateColumnDefinition(null, Engine.instance.Settings.FkPrefix + resolved.Name, resolved.Table.Index, KeyType.Foreign, resolved.ForeignTable.Index); definition = ColumnDefinition.InsertColumnDefinition(definition, Constraints); definition = ColumnDefinition.InsertColumnDefinition(definition.CleanForeignKey(), ColumnDefinitions); break; case RelationshipType.ManyToMany: TableDefinition relationTable = TableDefinition.CreateTableDefinition(typeof(RelationSkeleton), null, false, resolved.Table.Index + "_" + resolved.ForeignTable.Index + resolved.Override); definition = ColumnDefinition.CreateColumnDefinition(null, Engine.instance.Settings.FkPrefix + resolved.ForeignTable.Name + "_" + resolved.Table.Name, relationTable.Index, KeyType.Foreign, resolved.Table.Index); definition = ColumnDefinition.InsertColumnDefinition(definition, Constraints); definition = ColumnDefinition.InsertColumnDefinition(definition.CleanForeignKey(), ColumnDefinitions); definition = ColumnDefinition.CreateColumnDefinition(null, Engine.instance.Settings.FkPrefix + resolved.Table.Name + "_" + resolved.ForeignTable.Name, relationTable.Index, KeyType.Foreign, resolved.ForeignTable.Index); definition = ColumnDefinition.InsertColumnDefinition(definition, Constraints); definition = ColumnDefinition.InsertColumnDefinition(definition.CleanForeignKey(), ColumnDefinitions); break; default: break; } } }