EF v4.1 Code First and ASP.NET Membership Service
Entity Framework 4.1 Code First has really simplified the start for an application. You can virtually start File>New Project>New Class and start creating your Model.
For those that are unaware, EF Code First has a “Initializer” mechanism where you have to set if you wish to drop the database to re-recreate based on your Model and Relationship, as well as DbModelBuilder conventions that you may have set on your DataContext Class.
But once Model is created, you most definitely want to quickly scaffold the application that you wish to create. This most definitely will involve ASP.NET Membership classes interaction. But since EF Code First Drops the database every time the model changes, you have to run aspnet_regsql each time the database is dropped. This is a big annoyance once you get hold of it.
EF Team is working on something like an evolution of this approach, but when that is available is a good guess.
THE WORKAROUND!
If you are using SQL Server with your ASP.NET MVC Application, you are in luck!. Back since SQL Server 6.5(may be before that, I don’t know!), they used to ship something called a “Model” database. Whenever someone creates a new database in SQL Server, all the properties and tables of the “Model” database is inherited in the new database!.
So effectively you can run aspnet_regsql against your “Model” database in your development system and then each time Entity Framework creates a new database, it will inherit aspnet Application Service tables!
Now all that is remaining to do is to create sample users and roles. You can do this easily by inheriting a new class as :
public class MyDatabaseInitializer : DropCreateDatabaseIfModelChanges<YouDataContextClass>
{
protected override void Seed(YourDataContext context)
{
base.Seed(context);
//Add a User and Role Sample!
Membership.CreateUser("parag", "test123");
Roles.CreateRole("Admin");
Roles.AddUsersToRole(new[] {"parag"}, "Admin");
}
}
And you need to add this to your Global.asax in “Application_Start” :
Database.SetInitializer<YourDataContextClass>(new MyDatabaseInitializer());
Let me know if this helps!
EDIT : You need to enable “Role Manager” in web.config for roles to work.
Great site! Please continue the useful posts.
Excellent post – saved my Saturday! Thank you.
A few things I would mention, since others like myself might be finding this after already running into the issue on initialization. So, if you already have some initialization code:
1. Just add the following to your existing SampleData class (or whatever you called it):
// note: do NOT include the base.Seed(context) line, it will blow out your other data
Membership.CreateUser(“testuser”, “test123″);
Roles.CreateRole(“Administrator”);
Roles.AddUsersToRole(new[] {“testuser”}, “Administrator”);
2. Assuming you already have called SetInitializer with SampleData() in your Global.asax, you don’t need to add anything else.
Hopefully this helps someone save the extra hour I spend figuring this out. Again, this is a very helpful post and saved me countless hours.