ASP.NET SimpleMembershipProvider 的自动迁移
Posted
技术标签:
【中文标题】ASP.NET SimpleMembershipProvider 的自动迁移【英文标题】:Automatic Migrations for ASP.NET SimpleMembershipProvider 【发布时间】:2012-10-25 15:34:03 【问题描述】:所以我尝试在我的新 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
上写了一个配置类(从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 并不会改变任何事情。我想我错过了一些东西,但不知何故找不到什么。有什么想法吗?
【问题讨论】:
请看我在***.com/questions/26305273/…上的回答希望对您有所帮助... 【参考方案1】:update-database -verbose
不起作用,因为在您的数据表已经存在之后您的模型已更改。
首先,确保对 UserProfile 类没有任何更改。然后,运行:
Add-Migration InitialMigrations -IgnoreChanges
这应该会生成一个空白的“InitialMigration”文件。现在,向 UserProfile 类添加任何所需的更改。添加更改后,再次运行更新命令:
update-database -verbose
现在将应用自动迁移,并且表格将随着您的更改而改变。
【讨论】:
实际上这非常有效。不幸的是,我不能给你超过 +1 和接受的答案。你为我省去了很多麻烦。再次感谢。接下来是,我应该始终使用 Add-Migration InitialMigrations 吗?或者这只是第一次。我没有找到任何关于它的在线文档。 不客气。您只需运行一次即可创建一个 InitialMigrations 类。 您通过一个简单的选项“-IgnoreChanges”解决了我为期 2 天的问题。我应该能够点击 UpVote 100000 次。 如果我收到There is already an object named 'AspNetRoles' in the database.
,我应该在空白InitialMigration
文件中添加哪些更改?
这就像一个魅力。虽然我不明白为什么我需要使用 Add-Migration InitialMigrations -IgnoreChanges 创建初始迁移文件,但是当我删除我的数据库并重新创建它时。谁能解释一下?如果我添加空的初始迁移文件,我只能更新数据库。【参考方案2】:
这里发生的情况是您启用了迁移,然后运行了应用程序。通过在使用 UpdateDatabase 命令之前运行应用程序,EntityFramework 将创建并填充数据库,但由于启用迁移时数据库不存在,因此它没有创建 InitialCreate 迁移。 Migrations 仍然认为您有一个空数据库并希望创建模型中的所有对象
您可以尝试重新启用迁移,这将生成一个反映数据库当前状态的 InitialCreate 迁移。在这种情况下,我将保存您对种子方法所做的更改,而不是运行“Enable-Migrations -Force”,这应该重新创建迁移并生成 IntialCreate 迁移。然后,您可以重新填充种子方法并运行 UpdateDatabase 命令。
【讨论】:
【参考方案3】:我有相同的排序方式。去我的本地数据库删除了 UserProfile 和其他具有外键约束的表 pages_Membership、webpages_OAuthMembership、webpages_Roles、webpages_UsersInRoles 表。当您运行 update-database -verbose 时,所有这些都会重新创建。
【讨论】:
以上是关于ASP.NET SimpleMembershipProvider 的自动迁移的主要内容,如果未能解决你的问题,请参考以下文章