SqlHelper 使用EF-Core框架 连接池处理并发

2024-08-27 15:28

本文主要是介绍SqlHelper 使用EF-Core框架 连接池处理并发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

定义数据库

数据库名称:T_dicomPatientMsg

注意5大约束条件:

1.主键约束:primary key  IDKEY设置为主键,主键设置自增长

2.唯一性约束:unique

3.默认约束:default    所有值都要设置默认值,除了主键

4.检查约束:check

5.外键约束:foreign key

定义实体
 public class DicomPatientMsg{[Key]public int IDKEY { get; set; }        //设为主键,注意实体名称需要与数据库实体名称一致public string PatientID { get; set; }public string PatientName { get; set; }public DateTime PatientBirthDate { get; set; }public DateTime CheckDate { get; set; }public string PicturePath { get; set; }public string DicomFilePath { get; set; }public string SOPInstanceUID { get; set; }public string StudyID { get; set; }public string StudyInstanceUID { get; set; }public string SeriesInstanceUID { get; set; }public string InstanceNum { get; set; }public bool IsDelete { get; set; } }
SQL帮助类

连接池实现并发连接

public class SqlHelper
{private readonly AppDbContext _context;//构造函数注入DB_contextpublic SqlHelper(AppDbContext context){_context = context;}// 增加实体public async Task AddAsync<T>(T entity) where T : class{await _context.Set<T>().AddAsync(entity);await _context.SaveChangesAsync();}// 获取所有实体public async Task<List<T>> GetAllAsync<T>() where T : class{return await _context.Set<T>().ToListAsync();}// 根据ID获取实体public async Task<T> GetByIdAsync<T>(int id) where T : class{return await _context.Set<T>().FindAsync(id);}// 更新实体public async Task UpdateAsync<T>(T entity) where T : class{_context.Set<T>().Update(entity);await _context.SaveChangesAsync();}// 删除实体public async Task DeleteAsync<T>(T entity, bool isDelete = false) where T : class{if (isDelete){_context.Set<T>().Remove(entity);}else{var property = entity.GetType().GetProperty("IsDeleted");if (property != null && property.PropertyType == typeof(bool)){property.SetValue(entity, true);_context.Set<T>().Update(entity);}else{throw new InvalidOperationException("Error");}}await _context.SaveChangesAsync();}
}
 public async Task AddAsync<T>(T entity) where T : class{await _context.Set<T>().AddAsync(entity);await _context.SaveChangesAsync();}

//增加实体

public 表面方法是公开的,所有其他类都可以调用

async 表方法内可能包含异步操作,允许方法在内部使用"await"

await 在异步操作中使用,会暂停当前方法的执行(阻塞当前线程),直到方法执行完成后,才会继续执行下面的代码,暂停期间,控制权会返回给调用方(如UI线程)

Task 当一个 方法的返回类型是Task时,表面这个方法是异步的,但它不返回任何值(即它是'void'的异步版本,同理int的异步版本为Task<int>)。通过Task,调用者可以选择是否等待这个方法完成

AddAsync<T>(T entity)  T是泛型类型的参数,它使得这个方法可以处理任意类型的实体对象。T由调用者传入的entity类型所决定。如果不使用泛型,只处理某一实体类型如User,也可以写成AddUserAsync(User entity)

where T : class  约束条件,限制了T必须是一个类

 private readonly AppDbContext _context;//构造函数注入DB_contextpublic SqlHelper(AppDbContext context){_context = context;}

这里为什么要用构造函数去注入DbContext

DbContext通常代表数据库的会话(增删改查等),每个DbContext实例都代表与数据库的一次交互。

配置AppDbContext
public class AppDbContext : DbContext
{public AppDbContext(DbContextOptions<AppDbContext> options) : base(options){}// 定义数据库表public DbSet<DicomPatientMsg> T_dicomPatientMsg { get;set;}protected override void OnModelCreating(ModelBuilder modelBuilder){modelBuilder.Entity<DicomPatientMsg>().HasQueryFilter(e => !e.IsDelete);        //过滤已软删除的记录}}
在appsettings.json配置数据库连接字符串
{"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning","Microsoft.Hosting.Lifetime": "Information"}},"ConnectionStrings": {"DefaultConnection": "Server=.\\SQLEXPRESS;Database=Colposcope;User Id=sa;Password=123;TrustServerCertificate=True;"},"AllowedHosts": "*"
}//TrustServerCertificate=true  禁用SSL验证
注册DbContext 服务
// 从配置文件读取字符串
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");// 添加DbContext服务
builder.Services.AddDbContext<AppDbContext>((options) => options.UseSqlServer(connectionString));//添加SqlHelper,DicomFunc 和控制器类到 DI 容器
builder.Services.AddScoped<SqlHelper>();
builder.Services.AddScoped<DicomFunc>();
使用数据库
private readonly static SqlHelper sqlHelper = SqlHelper.Instance;DicomPatientMsg msg = new DicomPatientMsg()
{DicomFilePath = patientMsg.DicomFilePath,PatientID = patientMsg.PatientID,PatientName = patientMsg.PatientName,CheckDate = checkDate,PicturePath = patientMsg.PicturePath,SOPInstanceUID = dataset.GetString(DicomTag.SOPInstanceUID),StudyID = dataset.GetString(DicomTag.StudyID),StudyInstanceUID = dataset.GetString(DicomTag.StudyInstanceUID),SeriesInstanceUID = dataset.GetString(DicomTag.SeriesInstanceUID),InstanceNum = dataset.GetString(DicomTag.InstanceNumber),
};//存储到sql
await sqlHelper.AddAsync(msg);

下面理清一下这个数据库的使用流程:

1. 依赖链

 DicomController 依赖 DicomFunc,而 DicomFunc 依赖 SqlHelperSqlHelper 又依赖 AppDbContext

  • DicomController 依赖 DicomFunc
  • DicomFunc 依赖 SqlHelper
  • SqlHelper 依赖 AppDbContext

2. 服务注册

  • AppDbContext 的注册:使用 AddDbContext<AppDbContext> 将数据库上下文注册到 DI 容器中。这允许 SqlHelper 构造函数接收 AppDbContext 实例。
  • SqlHelper 的注册:我们使用 AddScoped<SqlHelper>() 注册 SqlHelper,让 DicomFunc 可以注入它。
  • DicomFunc 的注册:我们注册 DicomFunc,确保 DicomController 能够接收它。

3. 依赖注入的执行

当一个请求到达DicomController时,ASP.NET Core的依赖注入容器会

  1. 实例化 DicomController

    控制器依赖于 DicomFunc,容器会尝试实例化 DicomFunc
  2. 实例化 DicomFunc

    DicomFunc 的构造函数依赖于 SqlHelper,容器会进一步尝试实例化 SqlHelper
  3. 实例化 SqlHelper

    SqlHelper 的构造函数依赖于 AppDbContextAppDbContext 是通过 AddDbContext 方法注册到容器中的,它会被自动提供给 SqlHelper
  4. 实例化 AppDbContext

    容器会从依赖注入容器中提取并实例化 AppDbContext,这可能涉及数据库连接的初始化等操作。
  5. 完成实例化

    • 最终,AppDbContext 实例被注入到 SqlHelper 中。
    • SqlHelper 实例被注入到 DicomFunc 中。
    • DicomFunc 实例被注入到 DicomController 中。

这篇关于SqlHelper 使用EF-Core框架 连接池处理并发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112050

相关文章

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文

Java使用SLF4J记录不同级别日志的示例详解

《Java使用SLF4J记录不同级别日志的示例详解》SLF4J是一个简单的日志门面,它允许在运行时选择不同的日志实现,这篇文章主要为大家详细介绍了如何使用SLF4J记录不同级别日志,感兴趣的可以了解下... 目录一、SLF4J简介二、添加依赖三、配置Logback四、记录不同级别的日志五、总结一、SLF4J

使用Python实现一个优雅的异步定时器

《使用Python实现一个优雅的异步定时器》在Python中实现定时器功能是一个常见需求,尤其是在需要周期性执行任务的场景下,本文给大家介绍了基于asyncio和threading模块,可扩展的异步定... 目录需求背景代码1. 单例事件循环的实现2. 事件循环的运行与关闭3. 定时器核心逻辑4. 启动与停

如何使用Nginx配置将80端口重定向到443端口

《如何使用Nginx配置将80端口重定向到443端口》这篇文章主要为大家详细介绍了如何将Nginx配置为将HTTP(80端口)请求重定向到HTTPS(443端口),文中的示例代码讲解详细,有需要的小伙... 目录1. 创建或编辑Nginx配置文件2. 配置HTTP重定向到HTTPS3. 配置HTTPS服务器

Python处理函数调用超时的四种方法

《Python处理函数调用超时的四种方法》在实际开发过程中,我们可能会遇到一些场景,需要对函数的执行时间进行限制,例如,当一个函数执行时间过长时,可能会导致程序卡顿、资源占用过高,因此,在某些情况下,... 目录前言func-timeout1. 安装 func-timeout2. 基本用法自定义进程subp

SpringBoot中配置Redis连接池的完整指南

《SpringBoot中配置Redis连接池的完整指南》这篇文章主要为大家详细介绍了SpringBoot中配置Redis连接池的完整指南,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以... 目录一、添加依赖二、配置 Redis 连接池三、测试 Redis 操作四、完整示例代码(一)pom.

Java使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Qt中QUndoView控件的具体使用

《Qt中QUndoView控件的具体使用》QUndoView是Qt框架中用于可视化显示QUndoStack内容的控件,本文主要介绍了Qt中QUndoView控件的具体使用,具有一定的参考价值,感兴趣的... 目录引言一、QUndoView 的用途二、工作原理三、 如何与 QUnDOStack 配合使用四、自