asp net core中用efcore操作MySql数据库【包括事务回滚】

一、环境

  • 开发环境: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 需要更多手动控制
并发处理 内置支持 需要手动实现

猜你喜欢

转载自blog.csdn.net/dzj2021/article/details/141564818