因此,我尝试在新的MVC 4项目中使用自动迁移,但不知何故,它无法正常工作。我逐步followed this blog post

我已经将更改添加到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.**

我知道对象存在。我的意思是,我尝试使用自动迁移来精确地修改和运行,而无需手动重新创建数据库。但是,这不起作用。

我查看了MSDN文档并发现了该属性:
AutomaticMigrationDataLossAllowed = true;

但是将其设置为true不会改变任何东西。我想我缺少了一些东西,但是却找不到。任何想法?

最佳答案

update-database -verbose不起作用,因为在数据表已经存在之后,您的模型已更改。

首先,确保没有对UserProfile类进行任何更改。然后,运行:
Add-Migration InitialMigrations -IgnoreChanges
这将生成一个空白的“InitialMigration”文件。现在,将任何所需的更改添加到UserProfile类。添加更改后,再次运行update命令:
update-database -verbose
现在,将应用自动迁移,并且表将随着您的更改而更改。

10-02 00:02