.NET Core CLI
代码语言:javascript复制此种方法对于 ASP.NET Core 也可以使用,其实当执行命令
dotnet ef migrations
时,会启动所在程序集(Program.cs),和正常启动ASP.NET Core 一样,所以会依赖注入 MyDbContext等
# 全局安装 EF Core 工具
dotnet tool install --global dotnet-ef
# 安装 设计包,这是对项目运行命令所必需的
dotnet add package Microsoft.EntityFrameworkCore.Design
# migrations 命令为迁移搭建基架,以便为模型创建一组初始表
dotnet ef migrations add InitialCreate
# database update 命令创建数据库并向其应用新的迁移
dotnet ef database update
dotnet ef migrations add InitialCreate
创建描述表结构的代码文件
EF Core 有两个工具集
- .NET Core 命令行接口 (CLI) 工具可用于 Windows、Linux 或 macOS。 这些命令以
dotnet ef
开头。 - 包管理器控制台 (PMC) 工具在 Windows 上的 Visual Studio 中运行。 这些命令以动词开头,例如
Add-Migration
、Update-Database
。
为了跨平台 应用,同时也便于编写Shell脚本,建议使用 .NET Core CLI ,不依赖于 Visual Studio
在 ASP.NET Core 中初始化数据库
这是另一种创建表结构,初始化表数据的方式,而不是用CLI,这是在启动ASP.NET Core时执行。 用这种方法,无需
Migrations
代码文件,也无需b => b.MigrationsAssembly("WebApi")
,将在程序启动时,创建表结构(context.Database.EnsureCreated();),当然创建完表结构后,可以设定数据库种子(初始化表数据)
参考:ASP.NET Core 中的 Razor Pages 和 Entity Framework Core - 第 1 个教程(共 8 个) | Microsoft Docs
创建数据库
代码语言:javascript复制Program.cs
using ContosoUniversity.Data;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
namespace ContosoUniversity
{
public class Program
{
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
CreateDbIfNotExists(host);
host.Run();
}
private static void CreateDbIfNotExists(IHost host)
{
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<SchoolContext>();
context.Database.EnsureCreated();
// DbInitializer.Initialize(context);
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred creating the DB.");
}
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
如果有上下文的数据库,则 EnsureCreated 方法不执行任何操作。 如果没有数据库,则它将创建数据库和架构。 EnsureCreated
启用以下工作流来处理数据模型更改:
- 删除数据库。 任何现有数据丢失。
- 更改数据模型。 例如,添加
EmailAddress
字段。 - 运行应用。
EnsureCreated
创建具有新架构的数据库。
在无需保存数据的情况下,当架构快速发展时,此工作流在早期开发过程中表现良好。 如果需要保存已输入数据库的数据,情况就有所不同了。 如果是这种情况,请使用迁移。
设定数据库种子
代码语言:javascript复制Data/DbInitializer.cs
using ContosoUniversity.Data;
using ContosoUniversity.Models;
using System;
using System.Linq;
namespace ContosoUniversity.Data
{
public static class DbInitializer
{
public static void Initialize(SchoolContext context)
{
context.Database.EnsureCreated();
// Look for any students.
if (context.Students.Any())
{
return; // DB has been seeded
}
var students = new Student[]
{
new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2019-09-01")},
new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2017-09-01")},
new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2016-09-01")},
new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2018-09-01")},
new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2019-09-01")}
};
context.Students.AddRange(students);
context.SaveChanges();
}
}
Q&A
Q: EF Core 创建数据库 报错: 'Method 'Create' in type 'MySql.Data.EntityFrameworkCore.Query.Internal.My......
A: 降低设计器版本到 3.x
代码语言:javascript复制<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.7">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Q:
代码语言:javascript复制dotnet ef migrations add InitialCreate
代码语言:javascript复制Your target project 'WebApi' doesn't match your migrations assembly 'Repositories'. Either change your target project or change your migrations assembly.
Change your migrations assembly by using DbContextOptionsBuilder. E.g. options.UseSqlServer(connection, b => b.MigrationsAssembly("WebApi")). By default, the migrations assembly is the assembly containing the DbContext.
Change your target project to the migrations project by using the Package Manager Console's Default project drop-down list, or by executing "dotnet ef" from the directory containing the migrations project.
A: WebApi.Startup.ConfigureServices
services.AddDbContext<RemDbContext>(options =>
options.UseMySQL(connStr, b => b.MigrationsAssembly("WebApi")));
即, dotnet ef 的 默认 Migration 位于 DbContext 所在 Assembly,需要手动设置 MigrationsAssembly
WebApi
即 AssemblyName 可用下方代码获取
string migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
Q: 当多个 DbContext.Database.EnsureCreated()
时,只有第一个有效?
A: 是的,因为 EnsureCreated()
保证数据库被创建(存在),当第一个执行后,就会有数据库、表,
所以,当后面的 EnsureCreated()
执行时,由于已经存在数据库,所以不做任何操作
这个时候,只有对后面的调用 Migrate()
,例如下方:
this._applicationDbContext.Database.EnsureCreated();
this._configurationDbContext.Database.Migrate();
this._persistedGrantDbContext.Database.Migrate();
当然,也可以全部采用 Migrate():
代码语言:javascript复制this._applicationDbContext.Database.Migrate();
this._configurationDbContext.Database.Migrate();
this._persistedGrantDbContext.Database.Migrate();
注意:Migrate() 必须先生成 Migrations 代码文件,可使用 .NET CLI 生成:
代码语言:javascript复制dotnet ef migrations add InitialAspNetCoreIdentityDbMigration -c ApplicationDbContext -o Migrations/AspNetCoreIdentityDb
dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Migrations/IdentityServer/PersistedGrantDb
dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Migrations/IdentityServer/ConfigurationDb
参考
感谢帮助!
- 入门 - EF Core | Microsoft Docs
本文作者: yiyun
本文链接: https://moeci.com/posts/分类-dotnet/dotnet-efcore/
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!