什么是EFCore CLI
适用于Entity Framework Core的命令行接口(CLI)工具可执行设计时开发任务。例如,可以创建迁移、应用迁移,并为基于现有数据库的模型生成代码。
获取EFCore CLI
安装EFCore CLI
全局安装
dotnet tool install --global dotnet-ef
更新EFCore CLI
dotnet tool update --global dotnet-ef
卸载EFCore CLI
dotnet tool uninstall --global dotnet-ef
前置条件
通常使用EFCore CLI
之前,我们需要确保项目已经安装了Microsoft.EntityFrameworkCore.Design
,否则将会提示你
Your startup project 'xxxxxxxxxxx.EFSqliteConsole' doesn't reference Microsoft.EntityFrameworkCore.Design. This package is required for the Entity Framework Core Tools to work. Ensure your startup project is correct, install the package, and try again.
终端切换到项目根目录,使用命令行安装它
https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore.Design
如果是
Net Core 3.1
项目,最新的版本无法兼容,可以追加版本号参数--version 5.0.17
。
验证EFCore CLI
dotnet ef
管理迁移
建立示例项目(Sqlite)
依赖包
https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
如果是
Net Core 3.1
项目,最新的版本无法兼容,可以追加版本号参数--version 5.0.17
。
建立示例领域
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public List<Post> Posts { get; } = new List<Post>();
}
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; }
}
建立示例DbContext
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public string DbPath { get; }
public BloggingContext()
{
var folder = Environment.SpecialFolder.LocalApplicationData;
var path = Environment.GetFolderPath(folder);
DbPath = System.IO.Path.Join(path, "blogging.db");
}
// The following configures EF to create a Sqlite database file in the
// special "local" folder for your platform.
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite($"Data Source={DbPath}");
}
添加初始化迁移
dotnet ef migrations add $name
例如:
dotnet ef migrations add InitCreate
这个动作会创建一些迁移用的.cs
文件,默认存放在项目根目录的Migrations
文件夹中。
可选项
- 如果要修改这个目录路径,可以使用参数:
--output-dir|-o
指定。 - 如果要指定生成类的命名空间,可以使用参数:
--namespace|-n
指定。
列出可用的迁移
dotnet ef migrations list
可选项
- 如果要指定用于连接到数据库的连接字符串,可以使用参数:
--connection
指定,默认为AddDbContext
或OnConfiguring
中指定的值。 - 如果要指定不要连接到数据库,可以使用参数:
--no-connect
指定。
回退上次的迁移
删除上一次迁移,回退为上一次迁移所做的代码更改。
dotnet ef migrations remove
可选项
- 如果要如果连接到数据库时出错,则继续仅回退到代码更改,可以使用参数:
--force|-f
指定。
从迁移生成SQL脚本
我们可以基于迁移得到SQL脚本
dotnet ef migrations script $fromIndex $name
这里$fromIndex
默认值就是0
可选项
- 如果要指定生成脚本的文件路径,可以使用参数:
--output|-o
指定。 - 如果要生成可在任何迁移时用于数据库的脚本,可以使用参数:
--idempotent|-i
指定。 - 不要生成SQL事务语句,可以使用参数:
--no-transactions
指定。
例如从InitCreate
的首次迁移前到它自身包括的SQL脚本
dotnet ef migrations script 0 InitCreate
这时候我们给Blog领域模型增加一个Title字段
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public string Title { get; set; }
public List<Post> Posts { get; } = new List<Post>();
}
并且我们创建一个新的迁移UpdateBlogTitle
dotnet ef migrations add UpdateBlogTitle
这个时候,按道理就应该有两个迁移了,那么从InitCreate
之后迁移的所有SQL脚本,就能够生成第二次UpdateBlogTitle
的SQL脚本了
dotnet ef migrations script InitCreate
确实结果是这样的。
创建可执行文件更新数据库
dotnet ef migrations bundle
需要
>=Entity Framework Core 6.0.0
可选项
- 如果要指定要创建的可执行文件的路径,可以使用参数:
--output|-o
指定。 - 如果要覆盖现有文件,可以使用参数:
--force|-f
指定 - 如果要同时绑定.NET 运行时,因此不需要在计算机上安装它,可以使用参数:
--self-contained
指定 - 如果要要绑定的目标运行时,可以使用参数:
--target-runtime
指定
管理上下文
获取DbContext信息
dotnet ef dbcontext info
列出可用DbContext
dotnet ef dbcontext list
生成DbContext优化模型
dotnet ef dbcontext optimize
需要
>=Entity Framework Core 6.0.0
根据数据库生成代码
dotnet ef dbcontext scaffold $Connection $Provider
其中
$Connection
,用于连接到数据库的连接字符串。$Provider
,要使用的提供程序,通常,这是NuGet包的名称,例如Microsoft.EntityFrameworkCore.SqlServer
可选项
- 如果要使用属性配置模型,可以使用参数:
--data-annotations|-d
指定。 - 如果要指定生成的DbContext类的名称,可以使用参数:
--context
指定。 - 如果要指定放置DbContext类文件的目录,可以使用参数:
--context-dir
指定。 - 如果要指定生成的DbContext类的命名空间,可以使用参数:
--context-namespace
指定。 - 如果要覆盖现有文件,可以使用参数:
--force|-f
指定。 - 如果要指定放置实体类文件的目录,可以使用参数:
--output-dir|-o
指定。 - 如果要指定所有生成的类的命名空间,可以使用参数:
--namespace|-n
指定。 - 如果要指定生成实体类型的表的架构,可以使用参数:
--schema
指定。 - 如果要指定为其生成实体类型的表,可以使用参数:
--table|-t
指定。 - 如果要使用与数据库中显示的名称完全相同的表和列名,可以使用参数:
--use-database-names
指定。 - 如果要禁止在生成的DbContext类中生成OnConfiguring方法,可以使用参数:
--no-onconfiguring
指定。 - 请勿使用复数化程序,可以使用参数:
--no-pluralize
指定。
例如
dotnet ef dbcontext scaffold "Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -o Models
dotnet ef dbcontext scaffold "DataSource=C:\Users\TaylorShi\AppData\Local\blogging.db" Microsoft.EntityFrameworkCore.Sqlite -o Models
dotnet ef dbcontext scaffold "DataSource=C:\Users\TaylorShi\AppData\Local\blogging.db" Microsoft.EntityFrameworkCore.Sqlite -o Models -t Blogs -t Posts --context-dir Context -c BlogContext --context-namespace TeslaOrder.EFSqliteConsole
public partial class BlogContext : DbContext
{
public BlogContext()
{
}
public BlogContext(DbContextOptions<BlogContext> options)
: base(options)
{
}
public virtual DbSet<Blog> Blogs { get; set; }
public virtual DbSet<Post> Posts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
optionsBuilder.UseSqlite("DataSource=C:\\Users\\TaylorShi\\AppData\\Local\\blogging.db");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Post>(entity =>
{
entity.HasIndex(e => e.BlogId, "IX_Posts_BlogId");
entity.HasOne(d => d.Blog)
.WithMany(p => p.Posts)
.HasForeignKey(d => d.BlogId);
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
从DbContext生成SQL脚本
dotnet ef dbcontext script
可选项
- 如果要指定生成的SQL脚本文件,可以使用参数:
--output|-o
指定。 - 如果要指定DbContext,可以使用参数:
--context|-c
指定。
管理数据库
根据迁移更新数据库
dotnet ef database update $name
其中$name
可以指定迁移的迁移名称。
可选项
- 如果要指定用于连接到数据库的连接字符串,可以使用参数:
--connection
指定,默认为AddDbContext
或OnConfiguring
中指定的值。
例如,不带参数代表开始首次迁移之前并会还原所有迁移
dotnet ef database update
dotnet ef database update 20221031043138_UpdateBlogName
另外>=Entity Framework Core 5.0.0
还支持将其他参数传递到Program.CreateHostBuilder
中
dotnet ef database update -- --environment Production
其中--
之后所有内容都会被视为参数,它将转发给应用去处理。
删除数据库
dotnet ef database drop
可选项
- 如果不需要确认,直接删除,可以使用参数:
--force|-f
指定。 - 如果显示要删除的数据库,但不删除它,可以使用参数:
--dry-run
指定。
参考
- EF Core入门
- Entity Framework Core工具参考 - .NET Core CLI
- SQLite scaffolding with Entity Framework Core
- Understanding Entity Framework scaffold-dbcontext Commands in .NET Core
- 反向工程
- 创建和删除API
- 管理迁移
- EF Core 异步编程注意要点