web-dev-qa-db-ja.com

ASP.NET SimpleMembershipProviderの自動移行

そのため、新しいMVC 4プロジェクトで自動移行を使用しようとしましたが、どういうわけか機能しません。 I このブログ投稿に続いて ステップバイステップ。

UserProfileアカウントモデル(NotaryCodeフィールド)に変更を追加しました。

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }
    public int NotaryCode { get; set; }
}

次に、パッケージマネージャーコンソールでenable-migrationsに書き込み、Configurationクラスが表示され(DbMigrationsConfiguration<Web.Models.UsersContext>から継承)、次のようにクラスを入力します。

public Configuration()
{
    AutomaticMigrationsEnabled = true;
}

protected override void Seed(Atomic.Vesper.Cloud.Web.Models.UsersContext context)
{
    WebSecurity.InitializeDatabaseConnection(
            "DefaultConnection",
            "UserProfile",
            "UserId",
            "UserName", autoCreateTables: true);

    if (!Roles.RoleExists("Atomic"))
        Roles.CreateRole("Atomic");

    if (!Roles.RoleExists("Protocolista"))
        Roles.CreateRole("Protocolista");

    if (!Roles.RoleExists("Cliente"))
        Roles.CreateRole("Cliente");

    string adminUser = "randolf";

    if (!WebSecurity.UserExists(adminUser))
        WebSecurity.CreateUserAndAccount(
            adminUser,
            "12345",
            new { NotaryCode = -1 });

    if (!Roles.GetRolesForUser(adminUser).Contains("Atomic"))
        Roles.AddUsersToRoles(new[] { adminUser }, new[] { "Atomic" });
}

そして、update-database -verboseを実行しようとしましたが、これは機能しません。つまり、これは出力です:

データベースに「UserProfile」という名前のオブジェクトが既にあります。

PM> update-database -verbose
Using StartUp project 'Web'.
Using NuGet project 'Web'.
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Target database is: 'VesperCloud' (DataSource: .\SQLSERVER, Provider: System.Data.SqlClient, Origin: Configuration).
No pending code-based migrations.
Applying automatic migration: 201211051825098_AutomaticMigration.
CREATE TABLE [dbo].[UserProfile] (
    [UserId] [int] NOT NULL IDENTITY,
    [UserName] [nvarchar](max),
    [NotaryCode] [int] NOT NULL,
    CONSTRAINT [PK_dbo.UserProfile] PRIMARY KEY ([UserId])
)
System.Data.SqlClient.SqlException (0x80131904): There is already an object named 'UserProfile' in the database.
   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.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement)
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, XDocument targetModel, IEnumerable`1 operations, Boolean downgrading, Boolean auto)
   at System.Data.Entity.Migrations.DbMigrator.AutoMigrate(String migrationId, XDocument sourceModel, XDocument targetModel, Boolean downgrading)
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.AutoMigrate(String migrationId, XDocument sourceModel, XDocument targetModel, Boolean downgrading)
   at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
   at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.RunCore()
   at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run()
ClientConnectionId:a7da0ddb-bccf-490f-bc1e-ecd2eb4eab04
**There is already an object named 'UserProfile' in the database.**

オブジェクトが存在することを知っています。つまり、DBを手動で再作成せずに、自動移行を使用して、正確に変更して実行しようとしています。しかし、どういうわけかこれは機能していません。

MSDNドキュメントを見て、プロパティを見つけました。

AutomaticMigrationDataLossAllowed = true;

ただし、trueに設定しても何も変わりません。私は何かを逃していると思うが、どういうわけか見つけられない。何か案が?

43
Erre Efe

update-database -verboseは、データテーブルが既に存在した後にモデルが変更されたため機能しません。

最初に、UserProfileクラスに変更がないことを確認します。次に、実行します:

Add-Migration InitialMigrations -IgnoreChanges

これにより、空の「InitialMigration」ファイルが生成されます。ここで、必要な変更をUserProfileクラスに追加します。変更が追加されたら、更新コマンドを再度実行します。

update-database -verbose

これで自動移行が適用され、変更に応じてテーブルが変更されます。

127
Haminh Nguyen

ここで発生したように見えるのは、移行を有効にしてからアプリケーションを実行したことです。 UpdateDatabaseコマンドを使用する前にアプリケーションを実行すると、EntityFrameworkはデータベースを作成してデータを設定しますが、移行を有効にするとデータベースが存在しなかったため、InitialCreate移行は作成されませんでした。マイグレーションはまだ空のデータベースがあると考えており、モデル内のすべてのオブジェクトを作成したい

試行できるのは、データベースの現在の状態を反映するInitialCreate移行を生成する移行を再度有効にすることです。この場合、「Enable-Migrations -Force」を実行するよりもシードメソッドに加えた変更を保存します。これにより、移行が再作成され、IntialCreate移行が生成されます。その後、シードメソッドを再入力し、UpdateDatabaseコマンドを実行できます。

6
lukew

同じ方法で並べ替えました。ローカルデータベースに行って、UserProfileおよび外部キー制約webpages_OmberMembership、webpages_Roles、webpages_UsersInRolesテーブルを持つ他のテーブルを削除しました。 update-database -verboseを実行すると、これらすべてが再作成されます。

0
Chamilgreat