5

Entity Framework 4.4 を使用する ASP.NET MVC 4 アプリケーションを共有 Web ホスティング (GoDaddy-4GH プラットフォーム) にデプロイしようとしています。GoDaddy では、アプリケーション コードを使用してデータベースを作成できません。コントロール パネルから作成する必要がありました。

移行機能を使用して、スキーマを手動で変更せずにデータベースを進化させたいと考えています。

と を組み合わせて使用​​していIDatabaseInitializerますDbMigrationsConfiguration。db 初期化子は単に最新バージョンに移行します。

問題は、更新プロセス中に EF がEnsureDatabaseExistsメソッドを使用してデータベースが存在するかどうかを確認し、何らかの理由でデータベースが存在しないと判断した場合、先に進んで新しいデータベースを作成しようとすることですが、もちろん失敗します。

  1. EnsureDatabaseExistsが false を返す理由をデバッグするにはどうすればよいですか?
  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 サーバーの実装に何かがあり、それがこの機能不全を引き起こしていることに気づきました。「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 に答える