entity framework代码优先问题(SimpleMembership UserProfile表)

如果您使用过ASP.NET MVC 4,您会注意到Internet应用程序的默认设置是使用SimpleMembership提供程序,这一切都很好,并且工作正常。

问题来自于默认的数据库生成,他们为UserProfile定义了一个POCO,如下所示:

 [Table("UserProfile")] public class UserProfile { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int UserId { get; set; } public string UserName { get; set; } } 

..然后生成如下:

 using (var context = new UsersContext()) { if (!context.Database.Exists()) { // Create the SimpleMembership database without Entity Framework migration schema ((IObjectContextAdapter)context).ObjectContext.CreateDatabase(); } } 

这工作正常,数据库生成正常,工作没有问题。 但是,如果我要像这样更改POCO并删除数据库:

 [Table("UserProfile")] public class UserProfile { [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int UserId { get; set; } public string EmailAddress { get; set; } public string FirstName { get; set; } public string Surname { get; set; } public string Country { get; set; } public string CompanyName { get; set; } } 

仅生成前2列, UserIdEmailAddress 。 它工作得很好(代码登录/注册),但显然我的其他用户数据都没有存储。

我在这里错过了什么吗? 当然它应该基于整个UserProfile对象生成数据库。

1 – 您需要启用迁移,尤其是使用EntityFramework 5.在NuGet包管理器中使用Enable-Migrations

2 – 移动你的

 WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true); 

您的YourMvcApp / Migrations / Configuration.cs类中的Seed方法

  protected override void Seed(UsersContext context) { WebSecurity.InitializeDatabaseConnection( "DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true); if (!Roles.RoleExists("Administrator")) Roles.CreateRole("Administrator"); if (!WebSecurity.UserExists("lelong37")) WebSecurity.CreateUserAndAccount( "lelong37", "password", new {Mobile = "+19725000000", IsSmsVerified = false}); if (!Roles.GetRolesForUser("lelong37").Contains("Administrator")) Roles.AddUsersToRoles(new[] {"lelong37"}, new[] {"Administrator"}); } 

现在EF5将负责创建您的UserProfile表,在这样做之后,您将调用WebSecurity.InitializeDatabaseConnection以仅使用已创建的UserProfile表注册SimpleMembershipProvider,同时调用SimpleMembershipProvider哪个列是UserId和UserName。 我还展示了一个示例,说明如何添加用户,角色并将Seed方法中的两者与自定义UserProfile属性/字段相关联,例如用户的Mobile(数字)。

3 – 现在,当您从Package Manager控制台运行update-database时,EF5将为您的表配置所有自定义属性

有关其他参考资料,请参阅本文的源代码: http//blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom -user的属性/

看来我可能终于得到了这个,它可能只是一个巨大的误解。

事实certificate,我期待((IObjectContextAdapter)context).ObjectContext.CreateDatabase(); 做它根本不做的事情,即创建数据库中不存在的所有表,或者只是更新它们并且它们不同。

实际发生的是它实际上运行了一个CREATE DATABASE语句,对我来说这是最无用的事情。 除非你在一个非常奇怪的环境中工作,否则你总会有一个关闭的数据库,因此它总是存在(随后表创建永远不会发生!),我宁愿不给现实世界的用户访问无论如何要创建一个数据库。

无论如何,我通过使用DropCreateDatabaseIfModelChanges初始化程序解决了我想要UserProfile (和相关表)创建数据库的特定问题,并强制进行如下初始化:

 public SimpleMembershipInitializer() { #if DEBUG Database.SetInitializer(new DropCreateDatabaseIfModelChanges()); #else Database.SetInitializer(null); #endif try { using (var context = new DataContext()) { if (!context.Database.Exists()) { ((IObjectContextAdapter)context).ObjectContext.CreateDatabase(); } context.Database.Initialize(true); } WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true); } catch (Exception ex) { throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex); } } 

..这是有效的,非常适合开发,但在实践中相当无用,因为如果模型发生变化,它将从字面上删除数据库并从头开始重新创建它。 对我来说,这使得整个代码优先实践在它的默认forms中几乎无用,我可能最终会恢复到来自DB的edmx生成。

仍在创建的UserProfile表背后的“神秘”是WebSecurity.InitializeDatabaseConnection将根据您传入其中的字段初始化表,这就是创建EmailAddress而不是UserName原因,因为我已经更改了它在这。

我遇到了同样的问题。 我添加了代码,以便在SimpleMembershipInitializer中的“CreateDatabase”之前进行迁移。

这解决了我的问题,除了我相信现在我的迁移将在Azure中应用,无论发布配置文件中的设置如何。

  private class SimpleMembershipInitializer { public SimpleMembershipInitializer() { Database.SetInitializer(null); // forcing the application of the migrations so the users table is modified before // the code below tries to create it. var migrations = new MigrateDatabaseToLatestVersion(); var context = new WomContext(); migrations.InitializeDatabase(context); try {.... 

如果您没有计划在系统生效后进行更改,这只是在开发中发生而不是热衷于启用迁移。 尝试截断表__MigrationHistory。

 truncate table __MigrationHistory