Seven Color flower basic permission System (6)-let entityframework Code first auto Merge/migrate/data initialization

Source: Internet
Author: User
Tags create directory

In the previous section, we have been able to configure the mapping fields. But in the demo, we update the new field information (actually broken) to the database by deleting the original database and letting EF recreate it. This is obviously not acceptable to anyone. In this log, you will demonstrate how to automatically update the table structure in the database when an entity class changes and how to initialize a batch of data when the EF creates a database.

Merge/Migrate

Merging refers to the "new entity model mapping to a database, updating its structure", for example:

Added an entity class, which is a new data table in the database.

The entity class was deleted, and the data table was deleted in the database.

Add a property to an existing entity class, which in the database adds a field to the corresponding data table.

Delete the attribute in an existing entity class, which is the delete field for the corresponding data table in the database.

Modifies the name or type or configuration of an existing entity's properties,

Migration refers to "migrating data from older structures into new structures when updating the database structure."

Data initialization

Typically, when EF creates a database, it automatically adds a batch of data, which facilitates the development phase of data reset and testing. This is usually two words because EF can also reset the data at "merge", but this is not generally the case.

Manual mode

There are 2 manual methods of merging.

The first is to delete the original database and let EF recreate the database. This is seldom done after the project is carried out.

The second is to merge the old and new models with the NuGet command. Operation is too cumbersome, the development phase of the entity update frequency is high, time-consuming and laborious.

Automatic Merge/migration

Since the merge can be implemented in the way of NUGET commands, it can naturally be done automatically by code. EF provides a configuration portal for merging, with a small amount of code to complete the configuration.

Create a folder in S.framework.datacore/entityframework, name migrations, and create a merge configuration class in that folder.

1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.Linq;4 usingSystem.Text;5 usingSystem.Threading.Tasks;6 usingSystem.Data.Entity.Migrations;7 8 usings.framework.datacore.entityframework.entitycontexts;9 Ten namespaceS.framework.datacore.entityframework.migrations One{ A     // <summary> -     // Master Database Migration Policy -     // </summary> the     Internal Sealed classMastermigrateconfiguration:dbmigrationsconfiguration<masterentitycontext> -{ -         // <summary> -         /// construction method +         // </summary> -          PublicMastermigrateconfiguration () +{ A             //means turn on auto merge at              This. automaticmigrationsenabled =true; -             //Represents a merge that will result in data loss is also allowed -              This. automaticmigrationdatalossallowed =true; -} -} -} in 
Database Merge policy configuration class

The automaticmigrationdatalossallowed attribute expresses the fact that if data loss occurs when data is changed from the data type before the merge to the merged data type, it is forced to merge.

For example, nvarchar (1000) data is converted into int data, which is likely to result in data loss.

By the way 2 precautions.

First, when modifying a field's data type, it is recommended that a field be modified one field at a time, noting that the type conversion of the data is feasible. For example, to modify a property of type string to an attribute of type int, be aware that the field's data can be converted to int.

Second, when modifying the name of a field, do not directly update the database structure by automatically migrating. Because of this operation, EF handles the following: Delete the original field and add the new field. The data will be lost! The data will be lost! The data will be lost! Re-say 3. A more acceptable solution is to create a new field, automatically merge, write your own SQL to update the old field's data to the new field, and then delete the old field.

Third, when the automatic migration is turned on, do not manually modify the database structure directly. EF's Merge History table is a very sensitive one, not here, and there's a chance to start a new log.

The policy is configured and the EF database context needs to be known as well. EF provides a Setinitializer method for setting initialization policies on database objects.

Press Create directory structure and add a class named "Masterdatabaseinitializer" to represent the initialization class for the Master database.

This type of code is as follows:

1 usingSystem;2 usingSystem.Collections.Generic;3 usingSystem.Linq;4 usingSystem.Text;5 usingSystem.Threading.Tasks;6 usingSystem.Data.Entity;7 8 usings.framework.datacore.entityframework.entitycontexts;9 usingS.framework.datacore.entityframework.migrations;Ten  One namespaceS.framework.datacore.entityframework.initializes A{ -     // <summary> -     // Master Database initialization operation class the     // </summary> -      Public classMasterdatabaseinitializer -{ -         // <summary> +         /// Set database initialization policy -         // </summary> +         ///<param Name= "Migrate" > whether merging (Automatic migration). If it does, it checks whether the database exists, creates it if it does not exist, and automatically migrates if it exists. If no, the initialization operation is not performed (this avoids EF access to the sys.databases to detect if the database exists, and the parameter is set to False when the project is stable). </param> A          Public voidInitialize (BOOLMigrate at{ -             if(!migrate) -{ -System.data.entity.database.setinitializer<masterentitycontext> (NULL); -} -             Else in{ -System.Data.Entity.Database.SetInitializer (NewMigratedatabasetolatestversion<masterentitycontext, Migrateconfiguration> (true)); to} +} -} the} * 
master Database initialization class

The next step is to call the Initialize method in the above database initialization class in the Global.asax of the WebUI layer.

Since we encapsulate the content in global in the Shttpapplication class of the S.framework.web layer, and do not want the s.framework.web layer to refer to the S.framework.datacore layer (if you want to This reference is required to invoke the database initialization class, so let's make a slight adjustment to shttpapplication and add the following code:

  1protectedvirtualvoid applicationappend () {}

And at the end of the Application_Start, call the method:

  1this. Applicationappend ();

Then go to global to rewrite the above method:

  1protectedoverridevoid applicationappend ()  2 {  3      New Masterdatabaseinitializer (). Initialize (true);   4 }

Don't forget the using namespace.

Automatic Merge Migration Validation results

Make a slight adjustment to the "Add Admin user to database" code in Home/index, adding a verdict:

1  PublicActionResult Index ()2{3var db =NewMasterentitycontext ("Matrixkey");4 5     //Determine if admin exists, if present, do not add6     if(!db. Users.any (A = A.username = = "Admin"))7{8var entity =NewSysuser {ID = Guid.NewGuid (). ToString (), UserName = "Admin", Password ="123456", CreateDate = DateTime.Now, CreateUser ="Admin" };9         //Attaching a User object to a database context (this is only a memory-level operation)TenDb. Users.add (entity); One         //Database context Save changes (commit changes to database execution) ADb. SaveChanges (); -} -  the     returnView (); -}

Test steps: Compile build + DELETE database = run home page + Check database structure = Add a new property in sysrole such as Test1 = + Build again = run home + Check database structure = in SY A new property in srole such as Test2 = + compile build again = Run home page + Check database structure = Delete a property in sysrole such as Test1 = again compile build = run home page = Check database structure 。

Of course you can also add a new entity to test, similar to the above, and run after compiling. If you want to configure a field for a new entity, don't forget to run T4 (it's not wrong to run T4, but it's the default configuration).

Data initialization

After the automatic merge migration is complete, the data initialization is very simple because the entry for the data initialization is in the merge policy class.

Navigate to the Master Database Migration Policy (mastermigrateconfiguration), where the policy class inherits from Dbmigrationsconfiguration and goes to its definition, you can see a method:

(If you see the English version, it is recommended that you install the same version of Entityframework.zh-hans in NuGet and then reopen the VS project to have a Chinese effect.) )

This method can be overridden in the migration policy class to implement the data initialization function. Cut the code for that database operation in the Home/index, paste it into the seed method, and adjust the name of the database context object as follows:

1 // <summary>2 /// initialization of data3 // </summary>4 /// <param name= "context" ></param>5 protected Override voidSeed (Masterentitycontext context)6{7     //Determine if admin exists, if present, do not add8     if(!context. Users.any (A = A.username = = "Admin"))9{Tenvar entity =NewSysuser {ID = Guid.NewGuid (). ToString (), UserName = "Admin", Password ="123456", CreateDate = DateTime.Now, CreateUser ="Admin" }; One         //Attaching a User object to a database context (this is only a memory-level operation) AContext. Users.add (entity); -         //Database context Save changes (commit changes to database execution) -Context. SaveChanges (); the} -}

At this time there is only one sentence in Home/index "return View".

Data Initialization Validation Results

In order to detect the effect, the data in the user table is emptied first.

Compile, run.

At this point: the first page opened, but after checking the database found that the user table does not have new admin data.

This is because: to get EF to help you, you must first trigger the call of the EF database context.

Any changes to the model, the migration policy/initialization policy changes, and the seed method is executed when the EF database context call is triggered again.

Because of the reality of the home page, there is no call to the database context, so it is impossible to "open the home" to let EF execute the seed method.

Remember the "User Login" feature that was previously implemented, which is a ready-made call to the EF database context.

Open/account/login, user name and password arbitrary input, will trigger. After returning the result of the operation, check the database to see that the admin data has been created.

In the next section, the decoupling of data entities and data cores is demonstrated.

Seven Color flower basic permission System (6)-let entityframework Code first auto Merge/migrate/data initialization

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.