ASP.Net vNext 站点,为什么启动时会出现迁移相关的异常?

In an ASP.Net vNext site, why does a migrations-related exception appear at startup?

我没有定义迁移,但在长时间超时后,我仍然在启动时看到有关 __MigrationHistory table 的异常。

我的初始化代码如下所示:

public void ConfigureServices(IServiceCollection services)
{
  services.AddMvc();

  services.AddEntityFramework()
    .AddSqlServer()
    .AddDbContext<DiContext>(options => options.UseSqlServer(Configuration.Get("ConnectionString")));
}

public void Configure(IApplicationBuilder app)
{
  var loggerFactory = (ILoggerFactory)app.ApplicationServices.GetService(typeof(ILoggerFactory));
  loggerFactory.AddProvider(
      new DiagnosticsLoggerProvider(
        new SourceSwitch("SourceSwitch", "Information"),
        new ConsoleTraceListener()));

  Trace.WriteLine("Configure.");

  app.UseDefaultFiles();
  app.UseStaticFiles();
  app.UseErrorPage();
  app.UseDatabaseErrorPage();
  app.UseMvc(routes =>
  {
    routes.MapRoute(
      name: "default",
      template: "{controller}/{action}/{id?}",
      defaults: new { controller = "Home", action = "Index" });
    });
}

异常:

Microsoft.Data.Entity.Query.EntityQueryExecutor Error: 0 : An exception occurred in the data store while iterating the results of a query.
System.Data.SqlClient.SqlException (0x80131904): Invalid object name '__MigrationHistory'.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader()
   at Microsoft.Data.Entity.Relational.Query.QueryingEnumerable`1.Enumerator.MoveNext()
   at System.Linq.Enumerable.<SelectManyIterator>d__8`2.MoveNext()
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at Microsoft.Data.Entity.Query.LinqOperatorProvider.<_TrackEntities>d__1`2.MoveNext()
   at Microsoft.Data.Entity.Query.EntityQueryExecutor.EnumerableExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext()

如果您使用 ASP.NET 5 Starter Web 模板创建项目,ASP.NET Identity 包含一个临时解决方法,可以使用 ApplicationDbContext 构造函数中的迁移自动创建他们的数据库:

private static bool _created = false;

public ApplicationDbContext()
{            
    // Create the database and schema if it doesn't exist
    // This is a temporary workaround to create database until Entity Framework database migrations 
    // are supported in ASP.NET 5
    if (!_created)
    {
        Database.AsMigrationsEnabled().ApplyMigrations();
        _created = true;
    }
}

要禁用迁移,请移除其解决方法。 :)

否则,在 EF7 中,我们永远不会 运行 迁移或任何其他数据库创建逻辑,除非您的应用程序(或入门模板)调用方法来执行此操作。

原来罪魁祸首是IApplicationBuilder.UseDatabaseErrorPage。启动时的上游 SQL 错误导致呈现 Microsoft.AspNet.Diagnostics.Entity 数据库错误页面。数据库错误页面总是查询数据库的迁移以检查是否有任何迁移挂起,从而触发迁移系统尝试在我的问题中产生异常的查询。