一、环境
-
开发环境:Win11,VisualStudio2022,MySQL Server 8.0,.Net Core7.0
-
测试
二、MySQL和EFCore相关的包
用NuGet包管理器安装
三、数据库中设置
安装好MySQL数据库,做好基础设置,测试数据连接
用数据库管理软件登录:
四、创建数据库的表
本例只创建两个简单的表。
在创建一个标,后面用来进行数据库的事务操作。
五、dbContext的配置
1、配置的思路
2、DbContext类的实现
(1)公共构造函数和DbSet的定义
public class TodoContext : DbContext
{
public TodoContext(DbContextOptions<TodoContext> options) : base(options) { }
public DbSet<User> Users { get; set; }
public DbSet<UserLog> UserLogs { get; set; }
}
逐行解释:
public class TodoContext : DbContext{}
DbContext 是 Entity Framework Core 中的核心类,用于与数据库进行交互。本例定义了一个DbContext类型的对象TodoContext。
public TodoContext(DbContextOptions<TodoContext> options) : base(options) { }
这是 TodoContext 的构造函数。
它接受一个 DbContextOptions 类型的参数 options。
: base(options) 表示它将这个 options 参数传递给基类(DbContext)的构造函数。
这允许你在创建 TodoContext 实例时配置数据库连接等选项。
public DbSet<User> Users { get; set; }
public DbSet<UserLog> UserLogs { get; set; }
定义了两个表DbSet
(2)DbSet如何绑定(映射)到数据库中的某个表[Table(“DB中表的名字”)]
- 把Class User绑定到Table user
/// <summary>
/// User类映射到数据库中的哪一个表,映射到user表
/// </summary>
[Table("user")]
public class User
{
/// <summary>
/// name列【字段】
/// </summary>
[Key]
[Column("name")]
public string name { get; set; }
/// <summary>
/// pw列【字段】
/// </summary>
[Column("pw")]
public string pw { get; set; }
}
- 把Class UserLog绑定到Table userlog
/// <summary>
/// UserLog类映射到数据库中的哪一个表,映射到userlog表
/// </summary>
[Table("userlog")]
public class UserLog
{
[Key]
[Column("logInfo")]
public string logInfo { get; set; }
}
3、asp net core中添加服务
var builder = WebApplication.CreateBuilder(args);
//......
//连接字符串
string conStr = "Server=localhost;Database=testdb;Uid=root;Pwd=abcxyz;"; //连接字符串
builder.Services.AddDbContext<TodoContext>(opt => opt.UseMySQL(conStr)); //启用DbContext
var app = builder.Build();
4、数据库的增删插改
- insert
//【1】======增加用户======
//将信息Add到数据库中
var user = new User { name = "ldh2", pw = "123456" };
//这里如何获取todocontext对象呢
dbContext.Users.Add(user);
await dbContext.SaveChangesAsync();
- update
//【2】======修改用户======
dbContext.Users.Where(x => x.name == "ldh2").First().pw = "pw123456";
await dbContext.SaveChangesAsync();
- delete
//【3】======删除用户======
var userToDelete = dbContext.Users.Where(x => x.name == "ldh2").FirstOrDefault();
if (userToDelete != null)
{
dbContext.Users.Remove(userToDelete);
await dbContext.SaveChangesAsync();
}
5、数据库事务的使用
(1)在 users中添加一个item
(2)在userlogs表中添加一个日志信息
两个操作作为一个事务合并提交
using (var transaction = dbContext.Database.BeginTransaction())
{
try
{
//添加一个用户
var idx = dbContext.Users.Count();
var newUser = new User { name = $"ldh2{idx + 1}", pw = "123456" };
dbContext.Users.Add(newUser);
//日志文档添加东西
var idx2 = dbContext.UserLogs.Count();
var newLog = new UserLog { logInfo = $"添加了一个用户:{newUser} -{idx2}" };
dbContext.UserLogs.Add(newLog);
//提交事务
transaction.Commit();
}
catch (Exception e)
{
transaction.Rollback();
}
}
6、事务的失败和回滚
- 下面添加一个重复key,故意引发异常进行回滚
var name = dbContext.Users.First().name;
var newUser = new User { name = $"{name}", pw = "123456" }; //key重复,引发异常
- 提交事务,回滚事务
using (var transaction = dbContext.Database.BeginTransaction())
{
try
{
//添加一个用户
var name = dbContext.Users.First().name;
var newUser = new User { name = $"{name}", pw = "123456" }; //key重复,引发异常
dbContext.Users.Add(newUser);
//日志文档添加东西
var idx2 = dbContext.UserLogs.Count();
var newLog = new UserLog { logInfo = $"添加了一个用户:{newUser} -{idx2}" };
dbContext.UserLogs.Add(newLog);
//提交事务
transaction.Commit();
}
catch (Exception e)
{
transaction.Rollback();
}
}
7、DbContext中的DbSet与ADO.NET的异同
大概在2003~2007年间用过ado.net(暴露年龄了),所以有点迷惑DbSet和ADO.NET到底有什么关系,所以用ai帮我整了一篇差异(尚未人工仔细复核)。
当然,这里是上述 Markdown 表格的字符串格式:
指标特性 | DbSet (EF Core) | ADO.NET |
---|---|---|
抽象级别 | 高级抽象 | 低级抽象 |
编程模型 | 对象关系映射 (ORM) | 数据集、数据表 |
SQL 查询 | 主要使用 LINQ | 通常需要手写 SQL |
数据映射 | 自动映射到对象 | 需要手动映射 |
变更跟踪 | 自动跟踪实体变更 | 需要手动管理 |
性能控制 | 较少的底层控制 | 更细粒度的控制 |
使用场景 | 快速开发、复杂数据操作 | 需要精细控制和高性能 |
学习曲线 | 相对较陡 | 相对较缓 |
数据库独立性 | 较好 | 较差 |
代码量 | 通常较少 | 通常较多 |
底层实现 | 基于 ADO.NET | 直接实现 |
事务管理 | 简化的 API | 需要更多手动控制 |
并发处理 | 内置支持 | 需要手动实现 |