开发者

EF 4.1 Code First and Existing Database and .NET Membership

开发者 https://www.devze.com 2023-02-20 12:51 出处:网络
I have a database called ApplicationName_Development running on SQL Server 2008 R2 Developer edition on my development box.

I have a database called ApplicationName_Development running on SQL Server 2008 R2 Developer edition on my development box.

I added .NET membership tables to the database with no problem. When I tried to get Code First working I received the following error message:

The server encountered an error processing the request. The exception message is "Model compatibility cannot be checked because the database does not contain model metadata. Ensure that IncludeMetadataConvention has been added to the DbModelBuilder conventions.

After some googling, I discovered that I had to delete the database and let EF create the database. That's fi开发者_Go百科ne but I lost all my .NET membership tables. I can go back in and add the membership tables again but if my model changes and EF needs to recreate the database then I have to add the membership tables in again.

How do I get around this?


This is how code-first work. Main idea of code first is that you do not touch your database because it is responsibility of the model to create the database. If you want to customize your database you must create custom IDatabaseInitializer and add your custom SQL.

public class MyDbInitializer : DropCreateDatabaseIfModelChanges<MyContext>
{
    protected override void Seed(MyContext context)
    {
        // Here run your custom SQL commands
        context.Database.ExecuteSqlCommand("CREATE TABLE ....");
    }
}

Now you only need setup your cutom intializer on the startup of your application:

Database.SetInitializer<MyContext>(new MyDbInitializer());

If you don't want to do it this way you must manually maintain your database and set initializer to null.


Found a easier workaround here. I hope this helps.

http://www.paragm.com/ef-v4-1-code-first-and-asp-net-membership-service/


Another option could be to use the System.Web.Management namespace. I've had great success with the code below:

string connectionString = ConfigurationManager.ConnectionStrings["MyDatabaseContext"].ConnectionString;
string database = "MyDatabaseName";
SqlServices.Install(database, SqlFeatures.All, connectionString);

It will just create the database and after that you can add users with the standard membership API.


Here's another possibility.

If you look at the MvcMusicStore sample - there's a SampleData class that is responsible for seeding the database on a rebuild. The SampleData class inherits from DropCreateDatabaseIfModelChanges, and overrides the Seed method. This class is passed to the Database.SetInitializer in the Application_Start method in global.asax.

I was getting the same error as you until I changed the parent class of SampleData to CreateDatabaseIfNotExist.

Then you can override the Seed method to insert any data you desire at startup, without it blowing away the database.


While you are developing, create 2 databases and two connection strings. One for SqlMembership (using aspnet_regsql) and one for your EF Application. If you would like to merge them into a single DB in production, just change the connection string in web.config.release to be the same. Then, EF model changes will just drop your apps db and not your membership DB.

By treating your authentication component separately, you will naturally decouple your authentication system from your application system. Then, if you wish to change membership providers, you will be better setup.

As the system grows, you will likely need to support non-pure models without EF code first, so this is a good template for going down that path.


I found the easiest way without playing with anything else was the following.

I ran the application first time with DropAndRecreatedatabase always in the Initilizer.

This created my database for the first time.

Following this I changed this to DropCreateDatabaseIfModelChanges.

0

精彩评论

暂无评论...
验证码 换一张
取 消