我编写了一堆通用的C#辅助函数作为我的SQL查询的基础.所有null对象参数都转换为DBNull.Value.但是当目标列是varbinary时,它告诉我字符串类型与二进制类型不兼容,我必须转换.为什么我需要在C#中使用SqlDbType DBNull...
我编写了一堆通用的C#辅助函数作为我的SQL查询的基础.所有null对象参数都转换为DBNull.Value.但是当目标列是varbinary时,它告诉我字符串类型与二进制类型不兼容,我必须转换.
为什么我需要在C#中使用SqlDbType DBNull.Value?有没有通用的方法来解决这个问题?
// works for nvarchar but throws for varbinary columns
// notice the lack of SqlDbType as I don't know it for a null object
var param1 = new SqlParameter();
param1.Name = "@Param1";
param1.Value = DBNull.Value;
它是一个空的…它不需要任何类型. SQL服务器知道null的类型.在SQL中你说[Column] IS NULL而不是[Column] IS TYPE NULL.所以null是无类型的.并且从查询中解析目标列而不是SqlDbType.
我发现这非常不直观(显式输入空值).我想知道我是否遗漏了一些东西……
代码是这样的:
SqlCommand CreateCommand(string query, params object[] arguments) { ... }
// in here I walk the parameters and build the proper SqlParameter for them.
// this saves me from setting up the SqlParameters by hand.
PS:String = NVarChar和Binary表示VarBinary.认真…
PPS:对EF或类似的东西不感兴趣.
解决方法:
如果您没有显式设置SqlParameter的DBType – 它具有默认值SqlDBType.NVarchar(请参阅MDSN以供参考).
这就是你得到异常的原因 – 你的参数类型是NVarchar,但目标列是VarBinary.
请注意,您必须明确设置DBType,因为显然ADO.NET无法从DBNull.Value中推断出数据类型.
null不是一个类型 – 它只是缺少值,所以如果我给你null,你不能推断它是否缺少varchar,或者,例如,没有int.
UPDATE
我做了一些实验.让我们运行简单的代码:
SqlCommand cmd = new SqlCommand("select * from sometable where somecolumn = @Param1");
cmd.Connection = _MyConnection;
var param = new SqlParameter();
param.ParameterName = "@Param1";
param.Value = DBNull.Value;
cmd.Parameters.Add(param);
cmd.Connection.Open();
try
{
cmd.ExecuteNonQuery();
}
finally
{
cmd.Connection.Close();
}
正如我们从SQL Profiler中看到的,这将被转换为实际的SQL查询:
exec sp_executesql
N'select * from sometable where somecolumn = @Param1',
N'@Param1 nvarchar(4000)',
@Param1=NULL
所以,如果somecolumn数据类型不能从varchar隐式转换,我们肯定会遇到异常,因为@Param1数据类型显式设置为varchar.
初看起来 – 这可以是足够好的解释,对吧?
但有一个问题令我感到困惑.如果我们不执行直接查询,而是执行varbinary作为参数的“虚拟”存储过程,那么让我们说:
create procedure [dbo].[usp_Test]
(
@Param1 varbinary(max)
)
as
begin
set nocount on
select null
end
现在让我们试着把它称为:
SqlCommand cmd = new SqlCommand("dbo.usp_Test");
cmd.CommandType = CommandType.StoredProcedure;
... and so on (the rest of code dealing with parameter)
现在在SQL Profiler中我们将看到这样:
exec dbo.usp_Test @Param1=NULL
这很奇怪,因为如果没有明确规范参数类型,这绝对是合法的.实际上,如果我们在SQL Management Studio中调用它 – 我们不会得到任何异常.
这部分ADO.NET行为对我来说很奇怪.可能SQL Profiler没有显示完整的过程(尽管事实上我打开了所有事件跟踪),我不知道.
无论如何 – 建议仍然相同 – 始终明确指定SqlParameter的DBType.
本文标题为:c# – 为什么DBNull.Value需要一个合适的SqlDbType?
- Unity3D实现物体旋转缩放移动效果 2023-01-11
- Unity中 mesh生成斜坡的示例代码 2023-04-21
- Unity实现领取奖励特效 2023-03-14
- C#中String和StringBuilder的简介与区别 2023-01-06
- .netcore3.1项目发布到centos docker 2023-09-26
- 在centos7.5使用DockerFile构建镜像时报错“Error parsing reference: "microsoft/dotnet:2.2-aspnetcore-runtime 2023-09-26
- CSReid库在NetCore工作场景中的使用 2023-09-28
- ASP.NET Core 进程内与进程外的性能对比 2023-09-27
- C# 解决datagridview控件显示大量数据拖拉卡顿问题 2023-03-28
- Unity实现见缝插针小游戏 2023-02-16