You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对Dapper返回的对象自动执行AcceptChanges后续处理?

解决方案

方案一:全局钩子(推荐)

Dapper提供了静态的SqlMapper.OnMaterialized事件,可全局注册对象实例化后的处理逻辑,无需修改现有查询代码,完全满足“默认生效”的需求。

在应用启动阶段(比如Program.cs或Startup.cs的初始化逻辑中)添加以下代码:

using Dapper;
using System.ComponentModel;

// 全局注册对象实例化后的处理逻辑
SqlMapper.OnMaterialized += obj =>
{
    if (obj is IChangeTracking ict)
    {
        ict.AcceptChanges();
    }
};

注册后,所有通过Dapper反序列化生成的对象,只要实现了IChangeTracking接口,都会自动执行AcceptChanges()方法,完全透明无侵入。

注意事项:

  • 该事件是静态全局事件,只需注册一次,重复注册会导致逻辑多次执行;
  • 触发时机是对象属性映射完成之后,确保处理逻辑基于完整的实例数据。

方案二:扩展方法(按需启用)

如果不想全局生效,可通过扩展方法包装Dapper的查询方法,手动选择需要启用跟踪处理的查询:

using Dapper;
using System.ComponentModel;
using System.Data;
using System.Threading.Tasks;

public static class DapperTrackingExtensions
{
    public static async Task<IEnumerable<T>> QueryWithTrackingAsync<T>(
        this IDbConnection conn,
        string sql,
        object param = null,
        IDbTransaction transaction = null,
        int? commandTimeout = null,
        CommandType? commandType = null)
    {
        var results = await conn.QueryAsync<T>(sql, param, transaction, commandTimeout, commandType);
        
        foreach (var item in results)
        {
            if (item is IChangeTracking ict)
            {
                ict.AcceptChanges();
            }
        }
        
        return results;
    }
}

使用时替换原有的QueryAsync调用即可:

var persons = await conn.QueryWithTrackingAsync<Models.User>("Select * from [User]");
var companies = await conn.QueryWithTrackingAsync<Models.Company>("Select * from [Company]");

内容的提问来源于stack exchange,提问作者Infarch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 17:20:14