数据库“主”实体框架迁移中的CREATE DATABASE权限被拒绝

时间:2012-08-05 07:43:26

标签: entity-framework entity-framework-4

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

我想使用迁移功能来允许我的数据库发展,而无需手动修改架构。

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

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

  1. 如何调试EnsureDatabaseExists返回false的原因?
  2. 是否可以覆盖此行为? (从用反射查看代码看起来并不那样)
  3. 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
    

    谢谢你, IDO

1 个答案:

答案 0 :(得分:2)

我的虚拟主机( amen.fr )存在同样的问题。在 SEVERAL 天期间,我看了一下,我意识到在主机上配置类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
  }