所以我尝试在我的新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并不会改变任何内容。我想我错过了什么,但不知何故找不到什么。有什么想法吗?
答案 0 :(得分:127)
update-database -verbose
不起作用,因为您的数据表已经存在后,您的模型已被更改。
首先,确保UserProfile类没有任何更改。然后,运行:
Add-Migration InitialMigrations -IgnoreChanges
这应生成一个空白的“InitialMigration”文件。现在,将任何所需的更改添加到UserProfile类。添加更改后,再次运行update命令:
update-database -verbose
现在将应用自动迁移,表格将随您的更改而更改。
答案 1 :(得分:6)
这里发生的事情是你启用了迁移,然后运行了应用程序。通过在使用UpdateDatabase命令之前运行应用程序,EntityFramework将创建并填充数据库,但由于启用迁移时数据库不存在,因此它没有创建InitialCreate迁移。迁移仍然认为您有一个空数据库并且想要在模型中创建所有对象
您可以尝试重新启用迁移,这将生成反映数据库当前状态的InitialCreate迁移。在这种情况下,我会保存您对种子方法所做的更改而不是运行&#34; Enable-Migrations -Force&#34;,这应该重新创建迁移并生成IntialCreate迁移。然后,您可以重新填充种子方法并运行UpdateDatabase命令。
答案 2 :(得分:0)
我有同样的,并以不同的方式排序。去了我的本地db删除了UserProfile和其他具有外键约束的表webpages_Membership,webpages_OAuthMembership,webpages_Roles,webpages_UsersInRoles表。当您运行update-database -verbose时,所有这些都将重新创建。