/// <inheritdoc/> protected override IPathNode VisitDomainModel(DomainModel domainModel) { // Build tables, columns and primary indexes foreach (var primaryIndex in domainModel.RealIndexes.Where(i => i.IsPrimary)) { Visit(primaryIndex); } // Build full-text indexes foreach (var fullTextIndex in domainModel.FullTextIndexes) { Visit(fullTextIndex); } // Build foreign keys var buildForeignKeys = BuildForeignKeys && providerInfo.Supports(ProviderFeatures.ForeignKeyConstraints); if (buildForeignKeys) { foreach (var group in domainModel.Associations.Where(a => a.Ancestors.Count == 0)) { Visit(group); } } // Build keys and sequences foreach (KeyInfo keyInfo in domainModel.Hierarchies.Select(h => h.Key)) { Visit(keyInfo); } var buildHierarchyForeignKeys = BuildHierarchyForeignKeys && providerInfo.Supports(ProviderFeatures.ForeignKeyConstraints); if (!buildHierarchyForeignKeys) { return(targetModel); } // Build hierarchy foreign keys var indexPairs = new Dictionary <Pair <IndexInfo>, object>(); foreach (var type in domainModel.Types.Entities) { if (type.Hierarchy == null || type.Hierarchy.InheritanceSchema == InheritanceSchema.ConcreteTable) { continue; } if (type.Indexes.PrimaryIndex.IsVirtual) { Dictionary <TypeInfo, int> typeOrder = type.GetAncestors() .AddOne(type) .Select((t, i) => new { Type = t, Index = i }) .ToDictionary(a => a.Type, a => a.Index); List <IndexInfo> realPrimaryIndexes = type.Indexes.RealPrimaryIndexes .OrderBy(index => typeOrder[index.ReflectedType]) .ToList(); for (int i = 0; i < realPrimaryIndexes.Count - 1; i++) { if (realPrimaryIndexes[i] != realPrimaryIndexes[i + 1]) { var pair = new Pair <IndexInfo>(realPrimaryIndexes[i], realPrimaryIndexes[i + 1]); indexPairs[pair] = null; } } } } foreach (var indexPair in indexPairs.Keys) { var referencedIndex = indexPair.First; var referencingIndex = indexPair.Second; var referencingTable = targetModel.Tables[resolver.GetNodeName(referencingIndex.ReflectedType)]; var referencedTable = targetModel.Tables[resolver.GetNodeName(referencedIndex.ReflectedType)]; var storageReferencingIndex = FindIndex( referencingTable, referencingIndex.KeyColumns.Select(ci => ci.Key.Name).ToList()); string foreignKeyName = nameBuilder.BuildHierarchyForeignKeyName(referencingIndex.ReflectedType, referencedIndex.ReflectedType); CreateHierarchyForeignKey(referencingTable, referencedTable, storageReferencingIndex, foreignKeyName); } return(targetModel); }