新闻中心

Dapper怎么在后台服务(Worker Service)中使用 Dapper集成Worker Service

2025-12-13
浏览次数:
返回列表
Dapper 在 Worker Service 中需手动管理连接生命周期,推荐使用 Transient 注册或方法内 using 创建连接并显式 Open/Close。

dapper怎么在后台服务(worker service)中使用 dapper集成worker service

Dapper 在 .NET 后台服务(Worker Service)中使用,和在 Web API 或控制台应用里基本一致,核心是连接管理、依赖注入、生命周期适配三点。Worker Service 没有 HTTP 请求上下文,所以不能依赖 `Scoped` 生命周期来自动释放连接,得自己把控。

1. 安装必要 NuGet 包

确保项目包含以下包:

  • Dapper(核心 ORM 工具)
  • 对应数据库驱动:如 SQL Server 用 Microsoft.Data.SqlClient,MySQL 用 MySqlConnector,PostgreSQL 用 Npgsql
  • 配置相关(可选但推荐):Microsoft.Extensions.Configuration.JsonMicrosoft.Extensions.DependencyInjection

2. 配置连接字符串与注册服务

Program.cs 中读取 appsettings.json 并注册连接工厂(推荐封装为单例或 transient):

var builder = Host.CreateApplicationBuilder(args);
builder.Configuration.AddJsonFile("appsettings.json");
<p>builder.Services.AddSingleton<IDbConnection>(sp =>
{
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
return new SqlConnection(connectionString); // 或 MySqlConnection/NpgsqlConnection
});
// 或更推荐:注册一个工厂方法,每次调用新建连接(避免跨线程复用)
builder.Services.AddTransient<IDbConnection>(sp =>
{
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
var conn = new SqlConnection(connectionString);
conn.Open(); // Worker 中常需立即打开,避免 Execute 时才 Open 导致异常
return conn;
});

3. 在 Worker 类中使用 Dapper

通过构造函数注入 IDbConnection(注意:若注册为 Transient,每次注入都是新实例;若为 Singleton,务必手动管理 Open/Close,否则会出错):

public class DataSyncWorker : BackgroundService
{
    private readonly IDbConnection _connection;
    private readonly ILogger<DataSyncWorker> _logger;
<pre class="brush:php;toolbar:false;">public DataSyncWorker(IDbConnection connection, ILogger<DataSyncWorker> logger)
{
    _connection = connection;
    _logger = logger;
}

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    while (!stoppingToken.IsCancellationRequested)
    {
        try
        {
            // ✅ 安全写法:确保连接已打开(尤其注册为 Transient 时)
            if (_connection.State != ConnectionState.Open)
                _connection.Open();

            var count = await _connection.QuerySingleAsync<int>(
                "SELECT COUNT(*) FROM Orders WHERE Status = @Status",
                new { Status = "Pending" });

            _logger.LogInformation("待处理订单数: {Count}", count);

            // 执行更新等操作...
            await _connection.ExecuteAsync(
                "UPDATE Orders SET Status = 'Processed' WHERE Status = @Status",
                new { Status = "Pending" });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "数据同步失败");
        }

        await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
    }
}

}

⚠️ 注意:不要把连接设为 Singleton 并长期保持 Open 状态,容易引发连接池耗尽或超时断连。建议用 Transient + 每次操作前检查 Open 状态,或改用 using 块(见下条)。

Mistral AI Mistral AI

Mistral AI被称为“欧洲版的OpenAI”,也是目前欧洲最强的 LLM 大模型平台

Mistral AI 182 查看详情 Mistral AI

4. 更稳妥的连接用法(推荐)

直接在方法内创建并释放连接,完全规避生命周期争议:

private async Task ProcessOrdersAsync(CancellationToken ct)
{
    var connectionString = _configuration.GetConnectionString("DefaultConnection");
    using var conn = new SqlConnection(connectionString);
    await conn.OpenAsync(ct);
<pre class="brush:php;toolbar:false;">var orders = await conn.QueryAsync<Order>(
    "SELECT * FROM Orders WHERE CreatedAt > @Since",
    new { Since = DateTime.UtcNow.AddHours(-1) });

foreach (var order in orders)
{
    await conn.ExecuteAsync(
        "UPDATE Orders SET Status = 'Handled' WHERE Id = @Id",
        new { order.Id });
}

}

这种写法清晰、安全、符合 Dapper 原生习惯,也适配 Worker 的长周期运行场景。

基本上就这些。不复杂但容易忽略的是连接状态管理和释放时机——Worker 不像 Web 请求有天然作用域,得自己兜底。

以上就是Dapper怎么在后台服务(Worker Service)中使用 Dapper集成Worker Service的详细内容,更多请关注其它相关文章!


# 设为  # seo网站域名  # 定制网站建设与管理题  # 营销推广助理的发展方向  # 镇江网站制作与推广  # 杭州seo排名渠道  # 推广资质审核在哪个网站  # 泉州违规网站建设  # 宁波定制seo推广  # 大连网站搭建推广  # 福州关键词排名优化策略  # 中文网  # 相关文章  # 要把  # 推荐使用  # mysql  # 数据库查询  # 都是  # 的是  # 欧洲  # 如何使用  # .net  # 作用域  # nas  # microsoft  # ai  # 工具  # app  # json  # js 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 夸克浏览器网页版最新地址 夸克浏览器官方入口合集  抖音极速版最新版本 抖音极速版官方下载地址  css链接悬停下划线样式如何自定义_使用::after结合content和transition  Win11怎么查看显卡显存 Win11显示适配器属性及专用视频内存查询  Excel如何用迷你图显趋势_Excel用迷你图显趋势【趋势小图】  iCloud登录入口网页版 苹果iCloud官网登录  《燕云十六声》两周内达九百万玩家!位居畅销榜第五  ArchiveofOurOwn小说阅读-ArchiveofOurOwn同人作品访问链接  没有大陆身份证/银行卡如何实名微信? 亲测有效的几种方法分享  C++如何连接MySQL数据库_C++使用Connector/C++操作MySQL数据库教程  Excel函数批量查找替换超快方法_Excel用REPLACE和FIND函数秒级替换  如何创建没有密码的Windows本地账户_跳过微软账户登录的技巧【教程】  如何使用Node.js csv 包按条件移除含空字段的CSV记录  Win11 BitLocker密码忘了怎么办 Win11找回BitLocker恢复密钥方法【解决】  漫蛙manwa官网登录界面_漫蛙漫画网页版主站入口  HTML长属性值处理:表单action路径优化与代码规范应对  PySpark中高效提取字符串右侧可变长度数字:使用regexp_extract  蓝湖怎样用切图标注提对接效率_蓝湖用切图标注提对接效率【设计对接】  Golang如何使用const iota_Go iota常量计数器讲解  Composer如何解决json扩展缺失的错误  C++如何检测键盘输入_C++ _kbhit与_getch函数非阻塞输入  Golang如何实现状态模式管理对象状态_Golang State模式实现技巧  Python中高效且防溢出的双曲正弦计算:基于对数空间的优化策略  Tailwind CSS line-clamp 布局问题解析与修复指南  字由网在线版登录地址 字由网网页版安全入口  Python vgamepad库按键模拟:正确使用XUSB_BUTTON常量  163邮箱登录密码 163邮箱忘记密码找回  React列表渲染与独立状态管理:避免全局状态影响局部更新  利用Bokeh CustomJS动态控制DataTable列可见性  微信网页版登录教程_微信网页版登录入口在哪  我的世界mc.js免费游戏直接能玩 我的世界mc.js小游戏免费秒玩入口  J*aScript实现动态背景色下的文本与按钮颜色自适应调整  从J*aScript对象中精确提取指定属性的教程  如何解决电商平台定制报价请求的“黑洞”问题,SprykerQuoteRequest模块助你提升客户体验与销售效率  C#使用XPath查询节点时出错? 常见语法错误与调试技巧  ACG动漫视频网入口 ACG动漫*免费正版观看地址  谷歌邮箱注册显示错误Gmail服务器异常与延迟处理  Django模型中自动计算可用余额的实现方法  高德地图怎么看全景照片_高德地图全景照片浏览教程  淘宝网网页版登录入口 淘宝官方网页版快捷登录  Node.js CSV 数据处理:基于字段空值条件过滤整条记录的策略  海量存储:机器视觉智能化的核心基石  在J*a中如何在J*a中使用异常机制记录错误日志_异常日志实践经验  处理Kafka消费者会话超时:深入理解消息处理语义与幂等性  J*aScript Promise链中如何正确终止后续.then执行并处理错误  LINUX怎么设置定时任务_LINUX crontab配置教程  Tabulator表格日期时间排序问题及自定义解决方案  PDO预处理语句中冒号的正确处理:区分SQL函数格式与命名占位符  铁路12306改签能改到更早的车次吗_铁路12306改签提前车次规则  怎么在mac上运行html代码_mac运行html代码方法【指南】 

搜索