我编写了一堆通用的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?
基础教程推荐
- c#中多线程间的同步示例详解 2023-05-06
- Unity3D实现自动寻路 2023-03-04
- Unity解析gif动态图操作 2023-04-14
- 转载:.NET Core 图片操作在 Linux/Docker 下的坑 2023-09-27
- C#实现顺序队列和链队列的代码实例 2023-01-06
- C# 实现Zookeeper分布式锁的参考示例 2023-04-22
- WPF基础教程之元素绑定详解 2023-01-11
- 跳一跳自动跳跃C#代码实现 2022-12-02
- .net core 中实现一个堆结构 2023-09-27
- C# WPF后台动态添加控件实战教程 2023-06-08