5

我正在尝试将具有 Entity Framework 4.4 的 ASP.NET MVC 4 应用程序部署到共享 Web 托管(GoDaddy-4GH 平台)。在 GoDaddy 中,我无法使用应用程序代码创建数据库,我必须通过他们的控制面板创建数据库,我做到了。

我想使用迁移功能来让我的数据库在不手动修改架构的情况下发展。

我使用了IDatabaseInitializer和的组合DbMigrationsConfiguration。db 初始化程序只是迁移到最新版本。

问题在于,在更新过程中,EF 使用该EnsureDatabaseExists方法检查数据库是否存在,如果由于某种原因它决定不存在,那么它会继续尝试创建一个新数据库,这当然会失败。

  1. 如何调试为什么EnsureDatabaseExists返回错误?
  2. 是否可以覆盖此行为?(从用反射看代码看来不是这样)

DBMigration执行

public class DBMigrationInitializaer : IDatabaseInitializer<AppDbContext> {

public void InitializeDatabase(AppDbContext context) {
  bool dbExists;
  var mig = new DbMigrator(new MigrationConfiguration());
  mig.Update();

  Seed(context);
  context.SaveChanges();
}

protected virtual void Seed(AppDbContext context) {
  // TODO: put here your seed creation
}

异常堆栈跟踪

    [SqlException (0x80131904): CREATE DATABASE permission denied in database 'master'.]
   System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +2072894
   System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +5061932
   System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +234
   System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2275
   System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async) +228
   System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) +326
   System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +137
   System.Data.SqlClient.<>c__DisplayClassa.<DbCreateDatabase>b__7(SqlConnection conn) +38
   System.Data.SqlClient.SqlProviderServices.UsingConnection(SqlConnection sqlConnection, Action`1 act) +98
   System.Data.SqlClient.SqlProviderServices.UsingMasterConnection(SqlConnection sqlConnection, Action`1 act) +349
   System.Data.SqlClient.SqlProviderServices.DbCreateDatabase(DbConnection connection, Nullable`1 commandTimeout, StoreItemCollection storeItemCollection) +315
   System.Data.Objects.ObjectContext.CreateDatabase() +84
   System.Data.Entity.Migrations.Utilities.DatabaseCreator.Create(DbConnection connection) +73
   System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists() +76
   System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration) +44
   System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update() +12
   MvcApplication1.Models.MyDBInitializaer.InitializeDatabase(AppContext context) in MyDBInitializaer.cs:31
   System.Data.Entity.<>c__DisplayClass2`1.<SetInitializerInternal>b__0(DbContext c) +75
   System.Data.Entity.Internal.<>c__DisplayClass8.<PerformDatabaseInitialization>b__6() +19
   System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action) +72
   System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization() +186
   System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c) +7
   System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input) +118
   System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action) +190
   System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase() +73
   System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) +28
   System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() +56
   System.Data.Entity.Internal.Linq.InternalSet`1.GetEnumerator() +15
   System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable<TResult>.GetEnumerator() +40
   System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +315
   System.Linq.Enumerable.ToList(IEnumerable`1 source) +58
   MvcApplication1.Controllers.EmployeeController.Index() in EmployeeController.cs:21

谢谢你,伊多

4

1 回答 1

2

我的虚拟主机(amen.fr)也有同样的问题。在几天的时间里,我查看并意识到在主机上配置 DBMigrator 类和 sql server 的实现中有一些东西导致了这个功能障碍System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists ”无法检查正确的信息。这就是为什么与数据库的所有事务都是使用我的数据上下文进行的。这是允许我进行半自动迁移的代码:

public class Migrator
  {
    public static void RunMigrations()
    {
      //Configuration configuration = new Configuration();

      //configuration.ContextType = typeof(BOContext);//TODO Change to your DbContext
      //configuration.MigrationsAssembly = configuration.ContextType.Assembly;
      //configuration.MigrationsNamespace = "BO.Domain.Migrations";//TODO Namespace that contains your migrations classes
      //configuration.TargetDatabase = new DbConnectionInfo(context.Database.Connection.ConnectionString, "System.Data.SqlClient");

      //DbSeederMigrator<BOContext> migrator = new DbSeederMigrator<BOContext>(configuration);
      //migrator.MigrateToLatestVersion();

      using (BOContext context = new BOContext())
      {
        Configuration configuration = new Configuration();

        configuration.ContextType = typeof(BOContext);//TODO Change to your DbContext
        configuration.MigrationsAssembly = configuration.ContextType.Assembly;
        configuration.MigrationsNamespace = "CodeFirstMembershipSharp.Migrations";//TODO Namespace that contains your migrations classes
        configuration.TargetDatabase = new DbConnectionInfo(context.Database.Connection.ConnectionString, "System.Data.SqlClient");

        DbMigrator migrator = new DbMigrator(configuration);
        MigratorScriptingDecorator scriptor = new MigratorScriptingDecorator(migrator);

        var lm = migrator.GetLocalMigrations();// get local migration
        var dm = context.Database.SqlQuery<Migration>("select MigrationId from dbo.__MigrationHistory").Select(o => o.MigrationId); // get database migration
        List<string> pm = lm.Except(dm).ToList();// buil and set pending migration

        if (pm.Any())// Peding migration exists
        {
          string source = dm.Any() ? dm.OrderBy(o => o).Last() : DbMigrator.InitialDatabase;// get last to set source migration
          string target = pm.OrderBy(o => o).Last(); /// gest last to set target migration

          string sql = scriptor.ScriptUpdate(source, target); // buit sql script migration

          try { context.Database.ExecuteSqlCommand(sql); } // execute sql script migration
          catch (Exception e)
          {
            string spm = "Pending migrations : " + String.Join(";", pm.ToArray());
            string sdm = "Database migrations : " + String.Join(";", pm.ToArray());
            string[] tmp = { e.Message, spm, sdm, "Source : " + source, "Target : " + target, sql };

            throw new Exception(String.Join("\n-----------------\n", tmp));
          }
        }
      }

      //// TODO : code seed here
      //Migrator.Seed();
    }

    protected static void Seed()
    {
      //using (BOContext context = new BOContext())
      //{
      //  if (!context.Users.Any())
      //  {
      //    MembershipCreateStatus Status;
      //    Membership.CreateUser("Demo", "123456", "demo@demo.com", null, null, true, out Status);

      //    if (!context.Roles.Any(o => o.RoleName == "Admin"))
      //    {
      //      Roles.CreateRole("Admin");
      //      Roles.AddUserToRole("Demo", "Admin");
      //    }
      //  }
      //}
    }laguna-veneta
  }
于 2012-08-09T15:30:41.863 回答