我有一个存储过程,它的参数没有默认值,但它可以为空。但我不知道如何用 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 也会给我另一个错误。无法更改存储过程,它不属于我。
我认为你应该能够通过将
null
转换为适当的类型来做到这一点。假设 RouteId 是一个整数:
connection.Execute("spLMS_UpdateLMSLCarrier", new { RouteId = (int?)null, CarrierId = carrierID, UserId = userID, TotalRouteRateCarrierId = totalRouteRateCarrierId }, commandType: CommandType.StoredProcedure);
使用常规 null 时遇到的问题很可能是,当仅使用
RouteId
而不进行强制转换时,编译器无法推断匿名类型中 null
的类型。
我使用参数容器的方法略有不同,在我看来,这是比接受的回复更干净的解决方案。下面是我用来为 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 值,我认为您的用例需要它。只是还想记下来。