如何使用 Dapper 传递空参数

问题描述 投票:0回答:2

我有一个存储过程,它的参数没有默认值,但它可以为空。但我不知道如何用 Dapper 传递 null 。我可以在 ADO 中很好地完成。

connection.Execute("spLMS_UpdateLMSLCarrier", new { **RouteId = DBNull.Value**, CarrierId = carrierID, UserId = userID, TotalRouteRateCarrierId = totalRouteRateCarrierId },
                                        commandType: CommandType.StoredProcedure);

例外:

System.NotSupportedException was caught
  Message=The member RouteId of type System.DBNull cannot be used as a parameter value
  Source=Dapper
  StackTrace:
       at Dapper.SqlMapper.LookupDbType(Type type, String name) in C:\Dev\dapper-git\Dapper\SqlMapper.cs:line 348
       at Dapper.SqlMapper.CreateParamInfoGenerator(Identity identity) in C:\Dev\dapper-git\Dapper\SqlMapper.cs:line 1251
       at Dapper.SqlMapper.GetCacheInfo(Identity identity) in C:\Dev\dapper-git\Dapper\SqlMapper.cs:line 908
       at Dapper.SqlMapper.Execute(IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Nullable`1 commandTimeout, Nullable`1 commandType) in C:\Dev\dapper-git\Dapper\SqlMapper.cs:line 532
       at Rating.Domain.Services.OrderRatingQueueService.UpdateLMSLCarrier(Int32 totalRouteRateCarrierId, Int32 carrierID, Int32 userID) in C:\DevProjects\Component\Main\Source\Rating\Source\Rating.Domain\Services\OrderRatingQueueService.cs:line 52
       at Benchmarking.Program.OrderRatingQueue() in C:\DevProjects\Component\Main\Source\Benchmarking\Source\Benchmarking\Program.cs:line 81
       at Benchmarking.Program.Main(String[] args) in C:\DevProjects\Component\Main\Source\Benchmarking\Source\Benchmarking\Program.cs:line 28
  InnerException: 

无法关闭 RouteId,给我一个错误,指出它是必需的。不能使用常规 null 也会给我另一个错误。无法更改存储过程,它不属于我。

dapper
2个回答
92
投票

我认为你应该能够通过将

null
转换为适当的类型来做到这一点。假设 RouteId 是一个整数:

connection.Execute("spLMS_UpdateLMSLCarrier", new { RouteId = (int?)null, CarrierId = carrierID, UserId = userID, TotalRouteRateCarrierId = totalRouteRateCarrierId }, commandType: CommandType.StoredProcedure);

使用常规 null 时遇到的问题很可能是,当仅使用

RouteId
而不进行强制转换时,编译器无法推断匿名类型中
null
的类型。


0
投票

我使用参数容器的方法略有不同,在我看来,这是比接受的回复更干净的解决方案。下面是我用来为 nvarchar、int 和 guid 列提供 NULL 值的代码:

var exampleSql = "UPDATE TableName SET SomeColumn = @paramName1, SomeOtherColumn = @paramName2 WHERE SomeCondition";

DynamicParameters parameters = new DynamicParameters();
parameters.Add(name: "paramName1", dbType: DbType.String, value: DBNull.Value); // for int and nvarchar columns. yes, DbType.String does work for int columns too.
parameters.Add(name: "paramName2", dbType: DbType.Guid, value: DBNull.Value); // if it was a guid column, you would have to set DbType accordingly like this.

// then, execute query with the parameters
connection.Open();
int rowsAffected = connection.Execute(exampleSql, parameters);
connection.Close();

一个小小的烦恼是您必须为空参数声明 DbType,但此代码可以工作。 如果您的用例允许,您可以考虑不参数化空值,如下所示:

var exampleSql = "UPDATE TableName SET SomeColumn = NULL WHERE SomeCondition";

但是既然您询问如何参数化 NULL 值,我认为您的用例需要它。只是还想记下来。

© www.soinside.com 2019 - 2024. All rights reserved.