带有 DynamicParameters 的 Dapper 自定义 TypeHandler
Dapper custom TypeHandler with DynamicParameters
我在我的 Web-API 项目 (.NET Core 3.1) 中使用 Dapper,我正在尝试将记录插入数据库 (SQL Server 2017) + return创建的id.
我有这个对象...
public class CreateDetailGroupDto
{
public string Name { get; set; }
public List<CreateDetailDto> Details { get; set; }
}
负责的方法如下所示:
public async Task<int> Create(CreateDetailGroupDto detailGroup)
{
using var cnn = Connection;
var parameter = new DynamicParameters();
parameter.Add("detailGroup", detailGroup);
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;
}
我正在执行存储过程 spDetailGroup_Insert
,它需要上面的对象 JSON 格式 NVARCHAR(MAX)
并将 id 作为输出参数。
我写了一个处理程序,它应该在用作参数时序列化一个对象(我认为):
public class TypeHandler<T> : SqlMapper.TypeHandler<T>
{
public override T Parse(object value)
{
return JsonConvert.DeserializeObject<T>(value.ToString());
}
public override void SetValue(IDbDataParameter parameter, T value)
{
parameter.Value = JsonConvert.SerializeObject(value);
}
}
在 class 的构造函数中,我使用 SqlMapper.AddTypeHandler(new TypeHandler<CreateDetailGroupDto>());
为 DTO 添加 TypeHandler。但是...当Create
方法为运行时,即使成功执行了Handler中的SetValue
方法,对象也不会转换为JSON。
我知道这很具体,但是有人知道这里会发生什么吗?
编辑:
似乎在 SetValue 方法中添加一行以指定 DbType,似乎可以解决问题:
public override void SetValue(IDbDataParameter parameter, T value)
{
parameter.DbType = DbType.String;
parameter.Value = JsonConvert.SerializeObject(value);
}
基于 implementation of DynamicParameters,DbType 默认为空,所以我猜您在添加方法中缺少 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;
}
根据这个 documentation.
,nvarchar(max) 的正确映射应该是 DbType.String
我在我的 Web-API 项目 (.NET Core 3.1) 中使用 Dapper,我正在尝试将记录插入数据库 (SQL Server 2017) + return创建的id.
我有这个对象...
public class CreateDetailGroupDto
{
public string Name { get; set; }
public List<CreateDetailDto> Details { get; set; }
}
负责的方法如下所示:
public async Task<int> Create(CreateDetailGroupDto detailGroup)
{
using var cnn = Connection;
var parameter = new DynamicParameters();
parameter.Add("detailGroup", detailGroup);
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;
}
我正在执行存储过程 spDetailGroup_Insert
,它需要上面的对象 JSON 格式 NVARCHAR(MAX)
并将 id 作为输出参数。
我写了一个处理程序,它应该在用作参数时序列化一个对象(我认为):
public class TypeHandler<T> : SqlMapper.TypeHandler<T>
{
public override T Parse(object value)
{
return JsonConvert.DeserializeObject<T>(value.ToString());
}
public override void SetValue(IDbDataParameter parameter, T value)
{
parameter.Value = JsonConvert.SerializeObject(value);
}
}
在 class 的构造函数中,我使用 SqlMapper.AddTypeHandler(new TypeHandler<CreateDetailGroupDto>());
为 DTO 添加 TypeHandler。但是...当Create
方法为运行时,即使成功执行了Handler中的SetValue
方法,对象也不会转换为JSON。
我知道这很具体,但是有人知道这里会发生什么吗?
编辑:
似乎在 SetValue 方法中添加一行以指定 DbType,似乎可以解决问题:
public override void SetValue(IDbDataParameter parameter, T value)
{
parameter.DbType = DbType.String;
parameter.Value = JsonConvert.SerializeObject(value);
}
基于 implementation of DynamicParameters,DbType 默认为空,所以我猜您在添加方法中缺少 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;
}
根据这个 documentation.
,nvarchar(max) 的正确映射应该是 DbType.String