您的位置:首页 > 数据库

EntityFrameworkCore使用Migrations自动更新数据库

2017-03-02 11:42 591 查看

EntityFrameworkCore使用Migrations自动更新数据库

系统环境:Win10

IDE:VS2017 RC4

.netcore版本:1.1

一、新建ASP.NET Core WebApi项目

二、引用Microsoft.EntityFrameworkCore.Sqlite

使用VS Nuget工具,添加对
Microsoft.EntityFrameworkCore.Sqlite
库的引用,如使用其他数据库,添加相对应的引用即可。

三、使项目支持dotnet ef工具以使用Migrations

手动修改项目csproj文件

ItemGroup.DotNetCliToolReference
节点添加
Microsoft.EntityFrameworkCore.Tools.DotNet
工具的引用,注意版本
1.0.0-msbuild3-final
,VS2017 RC4 用的是MSBuild格式。

并在
ItemGroup.PackageReference
节点添加对
Microsoft.EntityFrameworkCore.Design
的引用,因为使用
dotnet ef migrations add
命令需要该引用。

<ItemGroup>
······
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.0" />
······
</ItemGroup>
<ItemGroup>
······
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0-msbuild3-final" />
</ItemGroup>

手动添加的原因是我在Nuget添加
Microsoft.EntityFrameworkCore.Tools.DotNet
时,报了一个错,可能是VS2017 RC版本的BUG:

Package 'Microsoft.EntityFrameworkCore.Tools.DotNet 1.1.0-preview4-final' has a package type 'DotnetCliTool' that is not supported by project 'EntityFrameworkCoreMigrationsDemo'.

CMD命令行cd到项目目录下(非Solution目录),执行
dotnet build
dotnet ef

C:\WorkSpacesC\DotNetCore\EntityFrameworkCoreMigrationsDemo\EntityFrameworkCoreMigrationsDemo>dotnet build
Microsoft (R) Build Engine version 15.1.545.13942
Copyright (C) Microsoft Corporation. All rights reserved.

Startup.cs(45,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call. [C:\WorkSpacesC\DotNetCore\EntityFrameworkCoreMigrationsDemo\EntityFrameworkCoreMigrationsDemo\EntityFrameworkCoreMigrationsDemo.csproj]
EntityFrameworkCoreMigrationsDemo -> C:\WorkSpacesC\DotNetCore\EntityFrameworkCoreMigrationsDemo\EntityFrameworkCoreMigrationsDemo\bin\Debug\netcoreapp1.0\EntityFrameworkCoreMigrationsDemo.dll

Build succeeded.

Startup.cs(45,13): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call. [C:\WorkSpacesC\DotNetCore\EntityFrameworkCoreMigrationsDemo\EntityFrameworkCoreMigrationsDemo\EntityFrameworkCoreMigrationsDemo.csproj]
1 Warning(s)
0 Error(s)

Time Elapsed 00:00:04.76

C:\WorkSpacesC\DotNetCore\EntityFrameworkCoreMigrationsDemo\EntityFrameworkCoreMigrationsDemo>dotnet ef

_/\__
---==/    \\
___  ___   |.    \|\
| __|| __|  |  )   \\\
| _| | _|   \_/ |  //|\\
|___||_|       /   \\\/\\

Entity Framework Core .NET Command Line Tools 1.0.0-msbuild3-final

Usage: dotnet ef [options] [command]

Options:
--version        Show version information
-h|--help        Show help information
-v|--verbose     Show verbose output.
--no-color       Don't colorize output.
--prefix-output  Prefix output with level.

Commands:
database    Commands to manage the database.
dbcontext   Commands to manage DbContext types.
migrations  Commands to manage migrations.

Use "dotnet ef [command] --help" for more information about a command.

可以看到EF独角兽,说明工具引用成功。

四、创建实例DbContext

新建DbContext以及相关Models

using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;

namespace EntityFrameworkCoreMigrationsDemo.Data
{
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Filename=./Blogging.db");
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }

public List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }

public int BlogId { get; set; }
public Blog Blog { get; set; }
}
}

在Startup将DbContext注册为服务

namespace EntityFrameworkCoreMigrationsDemo
{
public class Startup
{
······
public void ConfigureServices(IServiceCollection services)
{
······
services.AddDbContext<BloggingContext>();
}
······
}
}

五、使用Migrations

新建数据库初始化类
InitializeAsync.cs

using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;

namespace EntityFrameworkCoreMigrationsDemo.Data
{
public class DbInitializer
{
public async Task InitializeAsync(BloggingContext context)
{
//var migrations = await context.Database.GetPendingMigrationsAsync();//获取未应用的Migrations,不必要,MigrateAsync方法会自动处理
await context.Database.MigrateAsync();//根据Migrations修改/创建数据库
}
}
}

在Startup.cs的Configure方法中,添加参数
BloggingContext context
,netcore会使用DI将DbContext注入到Configure方法,并添加对
DbInitializer
的调用。

public class Startup
{
······
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, BloggingContext context)
{
······
new DbInitializer().InitializeAsync(context);
}
}

使用
dotnet ef
命令创建Migrations:
dotnet ef migrations add [NAME]


C:\WorkSpacesC\DotNetCore\EntityFrameworkCoreMigrationsDemo\EntityFrameworkCoreMigrationsDemo>dotnet ef migrations add Initial

Build succeeded.
0 Warning(s)
0 Error(s)

Time Elapsed 00:00:02.32
Done. To undo this action, use 'ef migrations remove'

执行成功后,可以看到项目目录下多了个文件夹
Migrations
,里面就是自动生成的Migrations文件。

创建更新Migrations的命令跟创建初始的一样,只是最后一个参数自己定义即可。

最后执行代码,成功创建了新的数据库,并且里面有一个表
__EFMigrationsHistory
,是自动生成的用来记录Migrations记录。

修改Blog类,添加一个字段
public string NewField { get; set; }
,在命令行执行命令
dotnet ef migrations add NewField
,然后运行程序,可以看到数据库已经更新,__EFMigrationsHistory表也多了一条对应的记录。

其他说明

因为我习惯使用VS,但是构建这个项目的过程中,需要使用到命令行,还需要手动修改csproj文件,所以这篇文章的操作过程有可能点乱,我自己在写Demo的时候,也是多次重启VS使VS能够加载最新的项目。

Demo源码,测试通过:Github

参考:

.NET Core - New Database Create your model

Walkthrough: Entity Framework Core 1.1 with Migrations
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: