Drizin / InterpolatedSql

Sql Builder using Interpolated Strings
MIT License
119 stars 7 forks source link

Nullability on generic typed FirstOrDefault/SingleOrDefault methods #19

Open j-caetano opened 1 month ago

j-caetano commented 1 month ago

Hey, found an issue regarding the null safety on return type of OrDefault methods on IDapperSqlBuilderExtensions as these methods can return null.

The FirstOrDefault/SingleOrDefault extension methods return non-nullable types while using the Dapper methods that return a nullable generic type.

Dapper:

public static Task<T?> QueryFirstOrDefaultAsync<T>(this IDbConnection cnn, string sql, object? param = null, IDbTransaction? transaction = null, int? commandTimeout = null, CommandType? commandType = null) =>
    QueryRowAsync<T?>(cnn, Row.FirstOrDefault, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default))

InterpolatedSql.Dapper: IDapperSqlBuilderExtensions.cs

public static T QueryFirstOrDefault<T>(this IDapperSqlBuilder builder, IDbTransaction? transaction = null, int? commandTimeout = null, CommandType? commandType = null)
{
    var command = builder.Build();
    return command.DbConnection.QueryFirstOrDefault<T>(sql: command.Sql, param: ParametersDictionary.LoadFrom(command), transaction: transaction, commandTimeout: commandTimeout, commandType: commandType);
}

Adding a nullable return type would solve the issue

public static T? QueryFirstOrDefault<T>(this IDapperSqlBuilder builder, IDbTransaction? transaction = null, int? commandTimeout = null, CommandType? commandType = null)
{
    var command = builder.Build();
    return command.DbConnection.QueryFirstOrDefault<T>(sql: command.Sql, param: ParametersDictionary.LoadFrom(command), transaction: transaction, commandTimeout: commandTimeout, commandType: commandType);
}
Drizin commented 1 month ago

Would you like to submit a PR?