| | | 1 | | #region Usings |
| | | 2 | | using ZhEaIsNsAaBn.DbSeeder; |
| | | 3 | | using ZhEaIsNsAaBn.DbSeeder.Registrations; |
| | | 4 | | #endregion |
| | | 5 | | |
| | | 6 | | // ReSharper disable once CheckNamespace |
| | | 7 | | namespace Microsoft.EntityFrameworkCore; |
| | | 8 | | |
| | | 9 | | /// <summary>Runs the seed migrations from EF's own seeding step.</summary> |
| | | 10 | | public static class DbSeederDbContextOptionsExtensions |
| | | 11 | | { |
| | | 12 | | /// <summary> |
| | | 13 | | /// Sets <b>both</b> <c>UseSeeding</c> and <c>UseAsyncSeeding</c> (EF tools and migration bundles call the sync one) |
| | | 14 | | /// <c>Database.Migrate[Async]()</c> / <c>EnsureCreated[Async]()</c> apply the pending seed migrations of the contex |
| | | 15 | | /// passes in. No seed lock is taken: EF already holds its migration lock. When EF has a transaction open, every mig |
| | | 16 | | /// The context type must be registered with <c>AddDbSeeder<TDbContext>()…Build()</c>. |
| | | 17 | | /// </summary> |
| | | 18 | | /// <param name="optionsBuilder">The context options.</param> |
| | | 19 | | /// <param name="serviceProvider">The provider from the <c>AddDbContext( ( serviceProvider, options ) => … )</c> |
| | | 20 | | /// <returns>The options builder.</returns> |
| | | 21 | | /// <exception cref="ArgumentNullException">An argument is <see langword="null"/>.</exception> |
| | | 22 | | /// <remarks> |
| | | 23 | | /// During seeding: <see cref="DbSeederException"/> (with the errors) when a seed migration fails, so <c>Migrate()</ |
| | | 24 | | /// <see cref="InvalidOperationException"/> when the context type has no <c>AddDbSeeder</c> registration. |
| | | 25 | | /// </remarks> |
| | | 26 | | /// <example> |
| | | 27 | | /// <code> |
| | | 28 | | /// services.AddDbContext<AppDbContext>( ( serviceProvider, options ) => |
| | | 29 | | /// options.UseSqlServer( connectionString ) |
| | | 30 | | /// .UseDbSeeder( serviceProvider ) ); |
| | | 31 | | /// </code> |
| | | 32 | | /// </example> |
| | | 33 | | public static DbContextOptionsBuilder UseDbSeeder( this DbContextOptionsBuilder optionsBuilder, IServiceProvider ser |
| | | 34 | | { |
| | 36 | 35 | | ArgumentNullException.ThrowIfNull( optionsBuilder ); |
| | 36 | 36 | | ArgumentNullException.ThrowIfNull( serviceProvider ); |
| | | 37 | | |
| | 36 | 38 | | return optionsBuilder.UseSeeding( ( context, _ ) => Throw( SyncPath.Result( RunAsync( context, serviceProvider, |
| | 36 | 39 | | .UseAsyncSeeding( async ( context, _, cancellationToken ) => Throw( await RunAsync( context |
| | | 40 | | } |
| | | 41 | | |
| | | 42 | | |
| | | 43 | | private static Task<LayerResponse<SeedRunResult>> RunAsync( DbContext context, IServiceProvider serviceProvider, boo |
| | | 44 | | { |
| | 24 | 45 | | var registration = serviceProvider.GetServices<SeedContextRegistration>().FirstOrDefault( r => r.ContextType == |
| | 24 | 46 | | ?? throw new InvalidOperationException( $"UseDbSeeder: {context.GetType().Name} has no AddDbSeed |
| | | 47 | | |
| | 24 | 48 | | var configuration = registration.Configuration; |
| | | 49 | | |
| | 24 | 50 | | return SeedEngine.UpAsync( context, configuration, configuration.CreateProvider( serviceProvider ), null, takeLo |
| | | 51 | | } |
| | | 52 | | |
| | | 53 | | private static void Throw( LayerResponse<SeedRunResult> result ) |
| | | 54 | | { |
| | 27 | 55 | | if ( result.IsFailure ) { throw new DbSeederException( result.Errors ); } |
| | 21 | 56 | | } |
| | | 57 | | } |