https://docs.microsoft.com/zh-cn/ef/core/
https://www.bilibili.com/video/BV1yd4y1T7p1/
Entity Framework(EF)Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术
EF Core可用作对象关系映射程序(O/RM),实现:
- 使.NET开发人员能够使用.NET对象处理数据库
- 无需再像通常那样自己手动编写sql语句访问数据库,而是通过EF Core(ORM) 自动生成sql语句访问数据库
新建一个项目
安装Sqlite包:
- Microsoft.EntityFrameworkCore
- Microsoft.EntityFrameworkCore.Sqlite
- Microsoft.EntityFrameworkCore.Design (用于迁移)
- Microsoft.EntityFrameworkCore.Tools (用于命令行迁移)
Microsoft.EntityFrameworkCore.Design包 提供了用于开发期间的设计时工具和命令行工具。它包含了一些在开发和管理 EFCore 数据库上下文和迁移时的用于生成代码、执行迁移和管理数据库结构变化的工具和命令行工具:
- 数据库上下文工具:该包提供了一些用于在开发期间生成数据库上下文类和实体类的工具。这些工具可以通过命令行或 Visual Studio 中的 Package Manager Console 来使用。
- 迁移工具:该包还提供了用于创建和应用数据库迁移的工具。迁移是一种管理数据库结构变化的方法,可以通过创建和应用迁移来保持数据库与代码模型的同步。
- 命令行工具:Microsoft.EntityFrameworkCore.Design 包还提供了一些命令行工具,可以通过命令行来执行数据库迁移和生成数据库上下文和实体类的代码。
项目根目录新建Models目录,目录中新建 Blog.cs 文件:
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
public class Blog{
[Key]
public int Id {get; set;}
[Comment("标题")]
public string Title {get; set;}
[Comment("内容")]
public string Content {get; set;}
[Comment("发布日期")]
public DateTime PostTime {get; set;} = DateTime.Now;
[Comment("访问流量")]
public int VisitCnt {get; set;}
}
根目录新建个 BlogContext.cs 文件
using XXX.Models;
using Microsoft.EntityFrameworkCore;
public class BlogContext : DbContext
{
// 注意,这里保存的路径为 /bin 目录中,如果直接填写 BlogDB.db 的话,运行迁移命令会生成到项目的根目录上
public string DBPath = Path.Combine(AppContext.BaseDirectory, "BlogDB.db");
// DbContext 实例表示与数据库的会话,可用于查询和保存实体的实例。 DbContext 是工作单元和存储库模式的组合。
//public BlogContext(DbContextOptions<BlogContext> options)
// : base(options)
//{
//}
/*
提供用于配置 Microsoft.EntityFrameworkCore.DbContextOptions 的简单 API 图面。
数据库(和其他扩展)通常在此对象上定义扩展方法,允许您配置要用于上下文的数据库连接(和其他选项)。
您可以使用 Microsoft.EntityFrameworkCore.DbContextOptionsBuilder 通过覆盖 Microsoft.EntityFrameworkCore.DbContext.OnConfiguring(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder) 或在外部创建 Microsoft.EntityFrameworkCore.DbContextOptions 并将其传递给上下文构造函数来配置上下文。
*/
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
if (!optionsBuilder.IsConfigured) {
//为了保护连接字符串中的潜在敏感信息,您应该将其移出源代码。 您可以使用 Name= 语法从配置中读取连接字符串,从而避免构建连接字符串 - 请参阅 https://go.microsoft.com/fwlink/?linkid=2131148。 有关存储连接字符串的更多指导,请参阅 http://go.microsoft.com/fwlink/?LinkId=723263
optionsBuilder.UseSqlite($"Data Source={DBPath}");
// optionsBuilder.LogTo(Console.WriteLine);
}
}
public DbSet<Blog> Blogs { get; set; }
}
然后将其生成表并执行入库(数据库迁移):
vsc:dotnet ef migrations add InitBlogContext
vs:Add-Migration InitialCreate
执行后,会在项目根目录上自动生成一个 Migratins 目录,以时间命名的cs文件就是要执行入库(Up)或者撤回(Down)的操作;
vsc:dotnet ef database update
vs:update-database
这条指令是用于执行 以时间命名的cs文件 的迁移文件,执行完后,就能在数据库中看到对应的Blogs表结构 和 出了一个 __EFMigrationsHistory表 用于记录每一次的迁移记录,好用于恢复回滚操作);
using XXX.Models;
using Microsoft.EntityFrameworkCore;
// new() 与 new BlogContext()等效, C# 9.0 中引入了新的语法简化,即在实例化对象时可以省略构造函数的参数列表。当构造函数没有参数时,可以使用 new() 的方式来实例化对象。这种简化的语法称为 Target-typed new 表达式。
BlogContext blogContext = new();
blogContext.Blogs.Add(new Blog
{
Title = "标题标题111",
Content = "内容内容1111",
VisitCnt = 33
});
blogContext.Database.EnsureCreated();
//blogContext.Database.Migrate();
// blogContext.Blogs.Remove(blogContext.Blogs.First(x=>x.VisitCnt == 3)); // 查询出访问量为3的数据并 删除 它
blogContext.Blogs.First(x => x.VisitCnt == 4).Content = "修改啦修改啦4444"; // 查询出访问量为4的数据并 修改 它
var blogs1 = blogContext.Blogs.AsNoTracking().First(s => s.VisitCnt == 4); // AsNoTracking 将查询后的结果移除跟踪
// blogs1.Content = "尝试修改下我"; // blogs1 因为已经移除了跟踪,所以这里的修改后,SaveChanges()是不会生效的(显示0行受影响)
int cnt = blogContext.SaveChanges();
Console.WriteLine($"影响了{cnt}行");
EnsureCreated()
用于确保数据库已经创建。如果数据库不存在,则会创建一个新的数据库,如果数据库已经存在,则不会做任何操作。
通常在应用程序启动时调用,以确保数据库的存在。它可以用于在应用程序第一次运行时创建数据库结构,或者在每次运行应用程序时都检查数据库是否存在。
这个方法主要用于开发和测试阶段,不建议在生产环境中使用。在生产环境中,通常会使用迁移工具(如Entity Framework Core的迁移)来管理数据库结构的变化。
EnsureCreated()
作用是应用尚未应用到数据库的所有迁移。它会检查数据库中的迁移历史记录,找到尚未应用的迁移,并按照定义的顺序将它们应用到数据库中,以确保数据库与代码模型的结构保持同步。它会自动检测并应用尚未应用的迁移,确保数据库的结构与代码模型保持一致。但是要注意:该方法只能应用迁移,而不能自动创建数据库。如果数据库尚未创建,你需要使用 EnsureCreated() 方法或其他方式先创建数据库,然后再应用迁移。
在 Models 目录中新建个 Post.cs 类:
pulic class Post{
public int Id {get; set;}
[Column(TypeName = "varchar(100)")]
public string Content {get; set;}
public DateTime PostTime {get; set;} = DateTime.Now;
}
在 Blogs.cs 中添加下面属性:
public List<Post> Posts {get; set;} = new List<Post>();
添加了模型,需要迁移:
add-migration CreatePost
update-database