43

所以我试图使用自动迁移与我的新MVC 4项目,但它不工作。我一步一步地走过去。自动迁移为ASP.NET SimpleMembershipProvider

我添加(在NotaryCode场)更改到UserProfile账户模型:

[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不会改变任何东西。我想我错过了一些东西,但不知何故没有找到。任何想法?

+0

请看看我的答案http://stackoverflow.com/questions/26305273/there-is-already-an-object-named-in-the-database/28316226#28316226 希望这会有所帮助... –

回答

127

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

首先,确保UserProfile类没有变化。然后,运行:

Add-Migration InitialMigrations -IgnoreChanges

这应该产生一个空白 “InitialMigration” 文件。现在,向UserProfile类添加所需的更改。一旦改变被添加,再次运行更新命令:

update-database -verbose

现在的自动迁移将应用和表格将根据您的变化而改变。

+5

其实这个工作完美。不幸的是我不能给你超过+1和接受的答案。你节省了我很多头痛。再次感谢。接下来的事情是,我应该总是使用Add-Migration InitialMigrations?或者这只是第一次。我没有找到任何关于它的在线文档。 –

+1

不客气。 您只需要运行一次即可创建一个InitialMigrations类。 –

+3

同样的问题。这个解决方案也适用于我。谢谢! +1 – kmehta

6

它看起来像在这里发生的是,您启用了迁移,然后运行该应用程序。通过在使用UpdateDatabase命令之前运行应用程序,EntityFramework将创建并填充数据库,但自从启用迁移时数据库不存在时,它不会创建InitialCreate迁移。迁移仍然认为你有一个空的数据库,并且想要创建模型中的所有对象

你可以尝试的是重新启用迁移,它将生成反映数据库当前状态的InitialCreate迁移。在这种情况下,我将保存对seed方法所做的更改,而不是运行“Enable-Migrations -Force”,这应该重新创建迁移并生成IntialCreate迁移。然后,您可以重新填充种子方法并运行UpdateDatabase命令。

+0

我已经试过(2天前)和nop。它不起作用。 –

0

我有同样的,并以不同的方式排序。去我的本地数据库删除UserProfile和其他表具有外键约束webpages_Membership,webpages_OAuthMembership,webpages_Roles,webpages_UsersInRoles表。所有这些将在您运行update-database -verbose时重新创建。