Use EF Core to update and modify the production database

Using EF Core's Code First, in the design phase, you can directly use Database.EnsureCreated()and EnsureDeleted()quickly delete and update the latest data structure. Since there is little data, the risk of deletion is very low. But for databases that have already been put into production, this method is absolutely not feasible.

Consider the following scenario:

The project has been launched, and the local test database has been used for development. Many database table structures have been added and modified locally. The online data is huge and updated in real time. Now the test needs to be launched.

If you need to update the production database, I can think of two ways:

use from the startMigration

From the beginning of the database design, use EF Migration to ensure that the database can be synchronized with the code, but when operating, you need to be extremely careful, be sure to check the generated updated database code, and directly connect to the production database.

Things to note:

  • Use it from the start Migration, never use Context.Database.EnsureCreated or EnsureDeleted statements.
  • After use Add-migration, do not delete the generated Migration files, which record the change history of the data structure.
  • Not all changes can be automatically recognized, such as "modifying the case of table column names". In this case, the data generated in many cases is deleted and then created, which is far from our original intention of renaming. So check out the page related to migrationBuilder.Drop in particular.

Using Scaffolds

If migration is not used for synchronization from the beginning, then EF Core will not be able to update directly, we need to work around:

Reverse Database to Model

First of all, the data structure of the database needs to be reversed to the model. We can use Scaffoldit. You can view the detailed documents here . It should be noted that in our scenario, there are already modified DataContext and Model. In the process of scaffolding, we must To specify outputdir and context, do not conflict with the current file.

According to your own preferences, choose whether to use -DataAnnotations, or use -table to specify the table to be modified, and the unspecified table will remain as it is. By default, EF Core will rename according to its own naming rules. If you want to keep your own routine, then use the -UseDatabaseNames parameter.

Add-Migration

I specified the output model to be placed in the Models folder, the original Models folder, I changed it to Models1, and changed the namespace to ensure that the project can now be compiled normally.

  • Exported model with DbConext: Models.Models namespace, Models folder
  • New model with DbConext: Models namespace, Models1 folder
    Next run Add-Migration.
add-migration initialcreate -context exportedContext

This will generate a snapshot and a migration file under the Migrations folder. snapshot is the tracking of the current database, and the other is the operation that the system will perform when using update-database. There are one Up()and one Down()method in it, Up is the operation of EF on the database when performing an update, and Down is to roll back the current change. Since this is the first time to execute add-migration, EF Core will think that the database is still empty, so there are a lot of statements in both methods, we delete all the statements related to create and drop. Leave the empty method.

App Migration, Synchronization

The preparatory work has been done before, and this step will directly operate the database. Use update-databaseto update the current migration to the database. Since our current data structure is exactly the same as that of the production database, we actually don’t need to perform any operations (delete the code inside Up and Down). Executing Update-Database just makes EF Core Link Models to the production database .

I understand that it is just adding __EFMigrationsHistoryrecords so that EF Core can follow up.

modify model content

Overwrite the files in Models1 with the files in Models. Due to the difference in type naming, some errors may be prompted, just modify it according to your own habits. The next step is to modify the model step by step, and often add-migration to observe whether the generated sentences are normal.

Since I used it Identity, there are corresponding tables at the beginning of the data AspNet. I do not use these tables in this system (other systems need to use them), so I deleted the corresponding model, snapshot, and DbContext records , ran Add-Migration, and generated The following files are created:

        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "AspNetRoleClaim");

            migrationBuilder.DropTable(
                name: "AspNetUserClaim");

            migrationBuilder.DropTable(
                name: "AspNetUserLogin");

            migrationBuilder.DropTable(
                name: "AspNetUserRoles");

            migrationBuilder.DropTable(
                name: "AspNetUserToken");

            migrationBuilder.DropTable(
                name: "AspNetRole");

            migrationBuilder.DropTable(
                name: "AspNetUser");
        }

It means that we can now track our modifications normally, but I need to keep the corresponding table here, so delete all the contents of up and down.

Note the following points:

update model name

If used fluentAPI, the table name corresponding to the model will be directly fluentAPIspecified in , and only modifying the name of the model has no effect. If you modify it, you can modify the corresponding fluentAPI, or use Annotation instead

Prompt can not find constraint

For the case of modifying the primary key, index, etc., if the database is not established through EF Core, the naming rules may be different. For the postgresql database, you can use this query name, and then modify the content of the corresponding migration file.

SELECT * FROM pg_CONSTRAINT

Composite Primary Key Limitations

For the case where two or more columns are used as a composite primary key, EnsureCreatedthe method used can recognize Annotationthe form of the primary key.

[Key]
[Column(Order = 1)]
public string DeviceId { get; set; }
[Key]
[Column(Order = 2)]
public long Timestamp { get; set; }

When using Migration, this form cannot be recognized and needs to OnModelCreating()be used in fluentAPI:

modelBuilder.Entity<DeviceData>().HasKey(w => new { w.DeviceId, w.Timestamp });

Command execution timed out

The default Commandexecution timeout setting is only 30s, which is not enough for some larger tables. You can set:

optionsBuilder.UseNpgsql("Server=xxxxxxxxxxxxx", opt=>opt.CommandTimeout(3000));

Increase the timeout for command execution.

The case of multiple connection strings

If the program uses appsettings.Development.jsonsuch a file to store the connection string, then you need to specify the environment Production(production database), otherwise it may be restored to the local database.
For the nuget package management console (using update-database), execute:

$Env:ASPNETCORE_ENVIRONMENT = "Development"
Update-Database

For those using the dotnet ef toolset, execute directly:

dotnet ef database update --environment Development

cannot be cast automatically to type

If you modify the data type of a column when designing a database table (for example, from varchar to integer), Postgresql will prompt this question, making it impossible to modify. You can migrationbuilderuse sql in , and follow the prompts to add "USING "x"::integer" to solve it. However, this method is still not very elegant. Up()After manual processing, it needs to be processed Down(), otherwise it will not be restored correctly.

This can be done using a step-by-step approach, assuming we need to varcharchange the Id from to int4.

  1. Add a field temp, the type is int4, set to [Key], and then delete the Id field.
  2. Add and apply migration
  3. Modify the temp name to Id
  4. Add and apply migration

Multiple application migrations

Try to make as few changes as possible each time, and then update-databaseit is easier to find problems. For those who have


For this prompt, be sure to check the Drop-related statements in the generated statement.

Both the local database and the production database have __EFMigrationsHistory records related migrations. When switching between production and local databases, there is no need to worry about the sequence. Update-Database will apply the migration one by one until the latest.

Summarize

The use of Migration can reduce a lot of workload in database synchronization, and it can be used reasonably to perform hot updates on production databases.

Note: This article passed the test under .NET 6 and EF Core 6.

Related Content Expansion: (Technical Frontier)

In the past 10 years, when even traditional enterprises began to digitize on a large scale, we found that in the process of developing internal tools, a large number of pages, scenes, components, etc. were constantly repeated. This repetitive work of reinventing the wheel wasted a lot of time for engineers.

In response to such problems, low-code visualizes certain recurring scenarios and processes into individual components, APIs, and database interfaces, avoiding repeated wheel creation. Greatly improved programmer productivity.

Recommend a software JNPF rapid development platform that programmers should know. This is a simple, cross-platform rapid development framework based on Java Boot/.Net Core. Thousands of commonly used classes are encapsulated in the front and back ends, which is convenient for expansion; the code generator is integrated to support front and back end business code generation, to achieve rapid development and improve work efficiency; the framework integrates forms, reports, charts, large screens and other commonly used Demo is easy to use directly; the backend framework supports Vue2 and Vue3.

Experience official website: https://www.jnpfsoft.com/?csdn

If you haven't understood the low-code technology, you can experience and learn it quickly!

Guess you like

Origin blog.csdn.net/Z__7Gk/article/details/132495307