Автоматическая миграция для ASP.NET SimpleMembershipProvider

Итак, я попытался использовать автоматические миграции с моим новым MVC 4 Project, но так или иначе не работает. я после этого блога шаг за шагом.

Я добавил изменения в модель учетной записи 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 и появился класс конфигурации (наследуемый от 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.**

Я знаю, что объект существует. Я имею в виду, я пытаюсь использовать автоматические миграции для, точно, модифицировать и запускать без повторного создания вручную БД. Но почему-то это не работает.

Я смотрю документацию MSDN и обнаружил свойство:

AutomaticMigrationDataLossAllowed = true;

Но установка его в true не изменяет ничего. Наверное, я что-то пропустил, но почему-то не нашел. Любая идея?

Ответ 1

update-database -verbose не работает, потому что ваша модель была изменена после того, как ваша таблица данных уже существует.

Во-первых, убедитесь, что в класс UserProfile нет изменений. Затем запустите:

Add-Migration InitialMigrations -IgnoreChanges

Это должно сгенерировать пустой файл "InitialMigration". Теперь добавьте любые желаемые изменения в класс UserProfile. После добавления изменений снова запустите команду обновления:

update-database -verbose

Теперь будет применена автоматическая миграция, и таблица будет изменена с вашими изменениями.

Ответ 2

Похоже, что здесь произошло, что вы включили миграции, а затем запустили приложение. Запустив приложение перед использованием команды UpdateDatabase, EntityFramework создала и заполнила базу данных, но так как при включении миграции база данных не существовала, она не создавала миграцию InitialCreate. Миграции по-прежнему считают, что у вас есть пустая база данных и вы хотите создать все объекты в вашей модели.

Что вы можете попробовать - либо повторно включить миграции, которые будут генерировать миграцию InitialCreate, которая отражает текущее состояние базы данных. В этом случае я бы сохранил изменения, внесенные вами в метод семени, чем запуск "Enable-Migrations -Force", это должно воссоздать миграцию и сгенерировать миграцию IntialCreate. Затем вы можете повторно заполнить свой метод семени и запустить команду UpdateDatabase.

Ответ 3

У меня был такой же и отсортированный по-разному. Пошел в мой локальный db, удалил UserProfile и другие таблицы с ограничениями внешнего ключа webpages_Membership, webpages_OAuthMembership, webpages_Roles, webpages_UsersInRoles. Все это будет воссоздаваться при запуске update-database -verbose.