Custom DbType for parameters not working.
ramonesz297 opened this issue · 2 comments
ramonesz297 commented
I tried to set DbType using DbValue attribute for parameters and looks like it is not use DbType property
[DapperAot(enabled: true)]
public static class UsersSqlQieries
{
public sealed class UserIncrementParams
{
[DbValue(Name = "userId")]
public int UserId { get; set; }
[DbValue(Name = "date", DbType = System.Data.DbType.Date)]
public DateTime Date { get; set; }
}
public static async Task IncrementAsync(DbConnection connection, int userId)
{
var date = DateTime.Today;
await connection.ExecuteAsync("""
UPDATE [dbo].[table]
SET [column] = ([column] + 1)
WHERE [Id] = @userId and [Date] = @date
""", new UserIncrementParams() { UserId = userId, Date = date });
}
}
and generated code:
file static class DapperGeneratedInterceptors
{
[global::System.Runtime.CompilerServices.InterceptsLocationAttribute("....cs", 25, 30)]
internal static global::System.Threading.Tasks.Task<int> ExecuteAsync4(this global::System.Data.IDbConnection cnn, string sql, object? param, global::System.Data.IDbTransaction? transaction, int? commandTimeout, global::System.Data.CommandType? commandType)
{
// Execute, Async, HasParameters, Text, KnownParameters
// takes parameter: global::App.Services.CompiledQueries.Sql.UsersSqlQieries.UserIncrementParams
// parameter map: Date UserId
global::System.Diagnostics.Debug.Assert(!string.IsNullOrWhiteSpace(sql));
global::System.Diagnostics.Debug.Assert((commandType ?? global::Dapper.DapperAotExtensions.GetCommandType(sql)) == global::System.Data.CommandType.Text);
global::System.Diagnostics.Debug.Assert(param is not null);
return global::Dapper.DapperAotExtensions.Command(cnn, transaction, sql, global::System.Data.CommandType.Text, commandTimeout.GetValueOrDefault(), CommandFactory2.Instance).ExecuteAsync((global::App.Services.CompiledQueries.Sql.UsersSqlQieries.UserIncrementParams)param!);
}
}
private sealed class CommandFactory2 : global::Dapper.CommandFactory<global::App.Services.CompiledQueries.Sql.UsersSqlQieries.UserIncrementParams>
{
internal static readonly CommandFactory2 Instance = new();
public override void AddParameters(in global::Dapper.UnifiedCommand cmd, global::App.Services.CompiledQueries.Sql.UsersSqlQieries.UserIncrementParams args)
{
var ps = cmd.Parameters;
global::System.Data.Common.DbParameter p;
p = cmd.CreateParameter();
p.ParameterName = "userId";
p.DbType = global::System.Data.DbType.Int32;
p.Direction = global::System.Data.ParameterDirection.Input;
p.Value = AsValue(args.UserId);
ps.Add(p);
p = cmd.CreateParameter();
p.ParameterName = "date";
p.DbType = global::System.Data.DbType.DateTime; //problem is here, DbType from DbValueAttribute not used
p.Direction = global::System.Data.ParameterDirection.Input;
p.Value = AsValue(args.Date);
ps.Add(p);
}
public override void UpdateParameters(in global::Dapper.UnifiedCommand cmd, global::App.Services.CompiledQueries.Sql.UsersSqlQieries.UserIncrementParams args)
{
var ps = cmd.Parameters;
ps[0].Value = AsValue(args.UserId);
ps[1].Value = AsValue(args.Date);
}
public override bool CanPrepare => true;
}
As I understood the problem in this method
Should it be?
public DbType? GetDbType(out string? readerMethod)
{
var dbType = IdentifyDbType(CodeType, out readerMethod);
if (TryGetAttributeValue(_dbValue, "DbType", out int explicitType, out bool isNull))
{
var preferredType = isNull ? (DbType?)null : (DbType)explicitType;
if (preferredType != dbType)
{ // only preserve the reader method if this matches
readerMethod = null;
dbType = preferredType; //added line
}
}
return dbType;
}
mgravell commented
fixed next release, thanks; output now (truncated, obviously):
p = cmd.CreateParameter();
p.ParameterName = "date";
p.DbType = global::System.Data.DbType.Date;
p.Direction = global::System.Data.ParameterDirection.Input;
p.Value = AsValue(args.Date);
ps.Add(p);