43

所以我尝试在我的新 MVC 4 项目中使用自动迁移,但不知何故它不起作用。我一步一步地关注了这篇博文。

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

I know the object exists. I mean, I'm try to use automatic-migrations to, precisely, modify and run without recreating manually the DB. But somehow this isn't working.

I look the MSDN documentation and found the property:

AutomaticMigrationDataLossAllowed = true;

But setting it to true doesn't change anything. I guess I'm missing something but somehow doesn't find what. Any idea?

4

3 回答 3

127

update-database -verbose doesn't work because your model has been changed after your data table already existed.

First, make sure there are no changes to the UserProfile class. Then, run:

Add-Migration InitialMigrations -IgnoreChanges

This should generate a blank "InitialMigration" file. Now, add any desired changes to the UserProfile class. Once changes are added, run the update command again:

update-database -verbose

Now the automatic migration will be applied and the table will be altered with your changes.

于 2012-11-09T08:56:31.917 回答
6

What it looks like happened here is that you enabled migrations, then ran the application. By running the application before using the UpdateDatabase command, EntityFramework would have created and populated the database but since when you enabled migrations the database didn't exist, it didn't create the InitialCreate migration. Migrations still thinks that you have an empty database and wants to create all of the objects in your model

What you can try is to either re-enable migrations which will generate an InitialCreate migration that reflects the current state of the database. In this case I would save the changes you made to the seed method than run "Enable-Migrations -Force", this should recreate the migration and generate an IntialCreate migration. You can then repopulate your seed method and run the UpdateDatabase command.

于 2012-11-07T19:38:46.113 回答
0

I had same and sorted in different way. Went to my local db deleted the UserProfile and other tables having foreign key constraints webpages_Membership,webpages_OAuthMembership,webpages_Roles,webpages_UsersInRoles tables. All these will recreate when you run update-database -verbose.

于 2015-09-20T10:54:39.033 回答