| File: HttpContextDatabaseContextDetailsExtensions.cs | Web Access |
| Project: src\aspnetcore\src\Middleware\Diagnostics.EntityFrameworkCore\src\Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.csproj (Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore; internal static class HttpContextDatabaseContextDetailsExtensions { [RequiresDynamicCode("DbContext migrations operations are not supported with NativeAOT")] public static async ValueTask<DatabaseContextDetails?> GetContextDetailsAsync(this HttpContext httpContext, Type dbcontextType, ILogger logger) { var context = (DbContext?)httpContext.RequestServices.GetService(dbcontextType); if (context == null) { logger.ContextNotRegisteredDatabaseErrorPageMiddleware(dbcontextType.FullName!); return null; } var relationalDatabaseCreator = context.GetService<IDatabaseCreator>() as IRelationalDatabaseCreator; if (relationalDatabaseCreator == null) { logger.NotRelationalDatabase(); return null; } var databaseExists = await relationalDatabaseCreator.ExistsAsync(); if (databaseExists) { databaseExists = await relationalDatabaseCreator.HasTablesAsync(); } var migrationsAssembly = context.GetService<IMigrationsAssembly>(); var modelDiffer = context.GetService<IMigrationsModelDiffer>(); var snapshotModel = migrationsAssembly.ModelSnapshot?.Model; if (snapshotModel != null) { snapshotModel = context.GetService<IModelRuntimeInitializer>().Initialize(snapshotModel); } // HasDifferences will return true if there is no model snapshot, but if there is an existing database // and no model snapshot then we don't want to show the error page since they are most likely targeting // and existing database and have just misconfigured their model return new DatabaseContextDetails( type: dbcontextType, databaseExists: databaseExists, pendingModelChanges: (!databaseExists || migrationsAssembly.ModelSnapshot != null) && modelDiffer.HasDifferences( snapshotModel?.GetRelationalModel(), context.GetService<IDesignTimeModel>().Model.GetRelationalModel()), pendingMigrations: databaseExists ? await context.Database.GetPendingMigrationsAsync() : context.Database.GetMigrations()); } }