| | | 1 | | namespace ZhEaIsNsAaBn.DbSeeder; |
| | | 2 | | |
| | | 3 | | /// <summary> |
| | | 4 | | /// Orders the tables of one migration by the EF model's foreign keys: principals before dependents (upserts); the rever |
| | | 5 | | /// Self-references are left out here (rows are levelled inside the table). Ties break by entity name, so the order is s |
| | | 6 | | /// </summary> |
| | | 7 | | internal static class SeedTableOrder |
| | | 8 | | { |
| | | 9 | | /// <returns>The upsert order; or the entities left in a cycle (no order exists).</returns> |
| | | 10 | | public static (IReadOnlyList<IEntityType>? Order, IReadOnlyList<string> Cycle) Sort( IReadOnlyCollection<IEntityType |
| | | 11 | | { |
| | 515 | 12 | | var set = entityTypes.ToHashSet(); |
| | 515 | 13 | | var principals = entityTypes.ToDictionary( t => t, t => t.GetForeignKeys() |
| | 515 | 14 | | .Select( k => k.PrincipalEntityType ) |
| | 515 | 15 | | .Where( p => p != t && set.Contains( p ) ) |
| | 515 | 16 | | .ToHashSet() ); |
| | 515 | 17 | | var order = new List<IEntityType>(); |
| | 515 | 18 | | var remaining = new SortedSet<IEntityType>( entityTypes, Comparer<IEntityType>.Create( ( a, b ) => string.Compa |
| | | 19 | | |
| | | 20 | | |
| | 1796 | 21 | | while ( remaining.Count > 0 ) |
| | | 22 | | { |
| | 1287 | 23 | | var ready = remaining.FirstOrDefault( t => principals[ t ].All( order.Contains ) ); |
| | | 24 | | |
| | 1293 | 25 | | if ( ready is null ) { return ( null, remaining.Select( t => t.Name ).ToList() ); } |
| | | 26 | | |
| | | 27 | | |
| | 1281 | 28 | | order.Add( ready ); |
| | 1281 | 29 | | remaining.Remove( ready ); |
| | | 30 | | } |
| | | 31 | | |
| | | 32 | | |
| | 509 | 33 | | return ( order, [] ); |
| | | 34 | | } |
| | | 35 | | } |