Códigos de Entity Framework Code-First (tabla de perfil de usuario de SimpleMembership)

Si ha usado ASP.NET MVC 4, notará que el valor predeterminado para una aplicación de Internet es usar el proveedor de SimpleMembership, todo está bien y funciona bien.

El problema viene con la generación de la base de datos predeterminada, tienen un POCO para UserProfile definido así:

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

.. que luego se genera así:

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

Esto funciona bien, la base de datos se genera muy bien y funciona sin problemas. Sin embargo, si debo cambiar el POCO de esta manera y eliminar la base de datos:

 [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; } } 

Solo se generan las 2 primeras columnas, UserId y EmailAddress . Funciona muy bien en cuanto al código (inicio de sesión / registro que habla), pero obviamente no se almacena ninguno de mis otros datos de usuario.

¿Me estoy perdiendo de algo? Seguramente debería generar la base de datos basada en el objeto UserProfile completo.

1 – Debe habilitar las migraciones, preferiblemente con EntityFramework 5. Utilice Enable-Migrations en el administrador de paquetes de NuGet.

2 – Mueve tu

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

a su método Seed en su clase YourMvcApp / Migrations / Configuration.cs

  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"}); } 

Ahora EF5 se encargará de crear su tabla UserProfile, después de hacerlo, llamará a WebSecurity.InitializeDatabaseConnection para registrar solo SimpleMembershipProvider con la tabla UserProfile ya creada, y le indicará a SimpleMembershipProvider qué columna es UserId y UserName. También estoy mostrando un ejemplo de cómo puede agregar usuarios, roles y asociar los dos en su método Seed con propiedades / campos personalizados del perfil de usuario, por ejemplo, el número de teléfono móvil de un usuario.

3 – Ahora, cuando ejecute la base de datos actualizada desde la Consola del Administrador de Paquetes, EF5 aprovisionará su tabla con todas sus propiedades personalizadas

Para referencias adicionales, consulte este artículo con el código fuente: http://blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom -usuario-propiedades /

Parece que finalmente pude entender esto, y puede que solo haya sido un gran malentendido.

Como resultado, esperaba ((IObjectContextAdapter)context).ObjectContext.CreateDatabase(); para hacer lo que simplemente no hace, que es crear todas las tablas en la base de datos que no existen, o simplemente actualizarlas si lo hacen y son diferentes.

Lo que realmente sucede es que, literalmente, ejecuta una CREATE DATABASE , que para mí es la cosa más inútil. A menos que esté trabajando en un entorno realmente extraño, siempre tendrá una base de datos apagada y, por lo tanto, siempre existirá (¡y, por lo tanto, la creación de la tabla nunca ocurrirá!), Prefiero no dar acceso a los usuarios del mundo real para crear una base de datos de todos modos.

De todos modos, resolví mi problema específico de querer que UserProfile (y las tablas relacionadas) crearan la base de datos utilizando el inicializador DropCreateDatabaseIfModelChanges y forzando una inicialización como la siguiente:

 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); } } 

… esto funciona y es perfecto para el desarrollo, pero es bastante inútil en la práctica, ya que literalmente eliminará la base de datos y la recreará desde cero si el modelo cambia. Para mí, esto hace que la práctica del código primero sea casi inútil en su forma predeterminada y probablemente termine volviendo a una generación de edmx desde DB.

El “misterio” detrás de la tabla UserProfile aún se está creando es que WebSecurity.InitializeDatabaseConnection inicializará la tabla si no existe en función de los campos que usted WebSecurity.InitializeDatabaseConnection , razón por la cual se creó EmailAddress lugar de UserName , porque cambié en esto

Yo estaba teniendo el mismo problema. Agregué código para que las migraciones sucedan justo antes de “CreateDatabase” en SimpleMembershipInitializer.

Eso me solucionó el problema, excepto que creo que ahora mis migraciones se aplicarán en Azure, independientemente de la configuración en el perfil de publicación.

  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 {.... 

Si no tiene planes de realizar cambios una vez que el sistema esté activo, esto solo está sucediendo en el desarrollo y no está interesado en habilitar las migraciones. Trate de truncar la tabla __MigrationHistory.

 truncate table __MigrationHistory