C# 带有DynamicParameters的简洁定制TypeHandler

C# 带有DynamicParameters的简洁定制TypeHandler,c#,dapper,C#,Dapper,我在我的Web API项目(.NET Core 3.1)中使用Dapper,并尝试将记录插入数据库(SQL Server 2017)+返回创建的id。 我有这个东西 public class CreateDetailGroupDto { public string Name { get; set; } public List<CreateDetailDto> Details { get; set; } } 在类的构造函数中,我使用SqlMapper.AddType

我在我的Web API项目(.NET Core 3.1)中使用Dapper,并尝试将记录插入数据库(SQL Server 2017)+返回创建的id。

我有这个东西

public class CreateDetailGroupDto
{
    public string Name { get; set; }

    public List<CreateDetailDto> Details { get; set; }
}
在类的构造函数中,我使用
SqlMapper.AddTypeHandler(newTypeHandler())
为DTO添加类型处理程序。然而。。。运行
Create
方法时,即使处理程序中的
SetValue
方法已成功执行,对象也不会转换为JSON

我知道这很具体,但有人知道这里可能发生了什么吗?

编辑:
似乎在SetValue方法中添加一行来指定DbType可以解决以下问题:

public override void SetValue(IDbDataParameter parameter, T value)
{
    parameter.DbType = DbType.String;
    parameter.Value = JsonConvert.SerializeObject(value);
}
基于此,DbType默认为null,因此我猜您在Add方法中缺少DbType规范:

public async Task<int> Create(CreateDetailGroupDto detailGroup)
{
    using var cnn = Connection;

    var parameter = new DynamicParameters();
    parameter.Add("detailGroup", detailGroup, DbType.String);
    parameter.Add("id", dbType: DbType.Int32, direction: ParameterDirection.Output);

    await cnn.ExecuteAsync("spDetailGroup_Insert", param: parameter, commandType: CommandType.StoredProcedure);

    int id = parameter.Get<int>("id");

    return id;
}
公共异步任务创建(CreateDetailGroupDto detailGroup)
{
使用var cnn=连接;
var参数=新的DynamicParameters();
参数.Add(“detailGroup”,detailGroup,DbType.String);
parameter.Add(“id”,dbType:dbType.Int32,direction:ParameterDirection.Output);
等待cnn.ExecuteAsync(“spDetailGroup_Insert”,param:parameter,commandType:commandType.storedProcess);
int id=parameter.Get(“id”);
返回id;
}

根据这一点,nvarchar(max)的正确映射应该是DbType.String。

这是正确的,但是我遇到了一个问题,处理程序中的SetValue方法没有运行。我认为我的问题与这个问题非常相似。通过查看您的编辑:我打算建议使用一个方法在这个SetValue中设置DbType,该方法基于映射检索DbType,因此如果您想对字符串以外的类型使用泛型TypeHandler,您将更加灵活。但如果你想继续使用字符串,你的解决方案是好的。
public override void SetValue(IDbDataParameter parameter, T value)
{
    parameter.DbType = DbType.String;
    parameter.Value = JsonConvert.SerializeObject(value);
}
public async Task<int> Create(CreateDetailGroupDto detailGroup)
{
    using var cnn = Connection;

    var parameter = new DynamicParameters();
    parameter.Add("detailGroup", detailGroup, DbType.String);
    parameter.Add("id", dbType: DbType.Int32, direction: ParameterDirection.Output);

    await cnn.ExecuteAsync("spDetailGroup_Insert", param: parameter, commandType: CommandType.StoredProcedure);

    int id = parameter.Get<int>("id");

    return id;
}