Non-destructive version based on IMLiviu's answer and comments:
Just came across this one problem and had to unknot the correct way to do it from the answer + comments (+ trial and error), so thought I would share the results you can cut & paste. This is based on the answer by IMLiviu, so full credit to them. It modifies the existing UserProfile
and UserContext
classes as they appear directly compatible with EF as-is:
I was horrified to see a suggestion that involved completely removing a database, just to add a few tables so after reading all the comments and creating a prototype, here's the result.
1 - Stop Webmatrix creation
Stop the standard webmatrix creation of the membership tables (comment out the [InitializeSimpleMembership] attribute).
[Authorize]
//[InitializeSimpleMembership]
public class AccountController : Controller
2 - Create a migration configuration
Create a migration configuration class like the one below:
public class MigrationConfiguration : DbMigrationsConfiguration<UsersContext>
{
public MigrationConfiguration()
{
this.AutomaticMigrationsEnabled = true; // This is important as it will fail in some environments (like Azure) by default
}
protected override void Seed(UsersContext context)
{
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
}
3 - Remove pluralisation from EF creation
Change the AccountModel.cs file UsersContext
class to remove the pluralisation option (added the OnModelCreating event):
public class UsersContext : DbContext
{
public UsersContext() : base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
4 - Add new fields to UserProfile
Add the extra fields you need to UserProfile:
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string UserEmail { get; set; } // <<<<<<<< E.G. THIS ADDED
}
5 - Migrate the tables on app start
Now when the app starts you set the database init strategy and trigger it with a read:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth();
Database.SetInitializer(new MigrateDatabaseToLatestVersion<UsersContext, MigrationConfiguration>());
new UsersContext().UserProfiles.Find(1);
}
Obviously you will need to add various using statements to get this all to work, but the right click resolve option will do that for you.
Additional notes:
If you decide (as I did) to use a table other than UserProfile
for your users, you need to change several entries to match.
- In your
SimpleMembershipInitializer
class you need to reference the new table and column names
- In the account controller and the various Login and Register views you need to reference your new model fields (if the names have changed)
- In the
UsersContext
class you can leave the Userprofile classname as-is, but you need to change the Table
attribute to match your table name.
- In the
UserProfile
class you need to rename the fields to match your new table field names.
- In the database you need to remove the relationship between
webpages_UsersInRoles
and UserProfile
and add a relationship between your new user table and webpages_UsersInRoles
or the old referential integrity checks will break you at run-time.
(I strongly recommend you delete the existing UserProfile
table and check it is not recreated. if it is you have something left behind in your code).