24

我目前正在尝试为数据库中的所有存储过程编写一个简单的 C# 包装类。

在 C# 中构建一些参数时,我注意到属性SqlParameter.IsNullable并想知道这是做什么用的。据我所知,不可能将存储过程参数声明为 NOT NULL,因此始终允许将 NULL 传递给任何参数。

通过测试,将 IsNullable 属性设置为 false 似乎没有任何效果,仍然允许将 SqlParameter.Value 属性设置为 null。

任何人都可以解释这个属性的目的吗?

感谢您的关注。

寻找赏金的回答者应查看以下链接:

如何将 NULL 限制为存储过程 SQL Server 的参数?

SQL 参数 IsNullable

我假设 SqlParameter.IsNullable 仅在……时才有意义?

http://social.msdn.microsoft.com/forums/en-US/vblanguage/thread/b7a08616-58d1-4cdc-a3e9-9353e292667b

4

2 回答 2

25

SqlParameter 类继承自抽象基类DbParameter,它定义了

    public abstract bool IsNullable {get; set;}

所以SqlParameter需要有一个公共的IsNullable属性实现。该类DbParameter是所有数据库参数实现的基类,包含在System.Data.

必须假设还有其他 DBMS 明确允许或拒绝将过程或函数参数明确定义为可空或不可空,并且SqlParameter.IsNullable仅因为 SqlParameter 实现更通用的通用数据库参数类和其他 .NET 通用的接口而存在数据库交互类。

查看反射器,SqlParameter该类不使用IsNullable,除了在将值转换为“InstanceDescriptor”时传递值。我没有深入研究InstanceDescriptor该类的用途,但我确实检查了SqlCommand该类,特别是该BuildParamList方法,该方法将 转换SqlParameterCollection为发送到数据库的参数的 SQL 字符串。

BuildParamList方法循环通过SqlParameterCollection, 并使用 aStringBuilder来构建参数字符串。BuildParamList不在IsNullable其实现中的任何地方使用属性或值。事实上,对的引用SqlParameter.IsNullable不会出现在 SqlCommand 类的任何地方。

我可能在某些将SqlParameter对象传递给不同类的内部/私有方法中错过了对它的引用,但如果该BuildParamList方法不使用它,那没关系,因为它不会影响发送到 SQL 的 SQL 字符串服务器。

除了您执行的测试用例之外,检查类的内容支持您可以安全地忽略属性值SqlCommand的结论。SqlParameter.IsNullable

在处理 SQL Server 方面,我在 Internet 上进行了快速搜索,以查看是否可以找到任何允许显式可为空/不可为空的过程或函数参数的 DBMS。当我遇到对 DB2 的引用时,我停下了脚步,该引用似乎需要在过程上设置特定属性以允许将空值传递给它。我不知道任何具有此功能的当代 RDBMS,而且我的搜索没有产生任何其他结果。

于 2012-06-22T00:03:07.687 回答
3

在查看了链接并阅读了 MSDN 上的几篇文章之后。

SqlParameter.IsNullable 属性实现接口IDataParameter.IsNullable并阅读一篇文章,它指出“使用 DBNull 类处理空值”

DBNull类只实现了一个接口方法IConvertible.ToType Infrastructure。将当前的 DBNull 对象转换为指定的类型。”其中还指出“DBNull.Value可用于将不存在的值显式分配给数据库字段,尽管大多数 ADO.NET 数据提供程序会在字段没有有效值时自动分配 DBNull 值"

读到这意味着大多数 ADO.NET 类自动实现了这个属性,并在图片后面进行 NULL 到 DBNull 的类型转换。根据我的理解,我假设如果我们使用writing our own APIeg( System.Data.CustomDatabaseClient,而不是System.Data.SqlClient) 来建立连接和其他数据库任务并且我没有实现这个属性,那么任何使用 System.Data.CustomDatabaseClient 的人都必须将 Null 值显式转换为 DBNull。

寻找您的意见和任何更正

于 2012-06-21T16:52:36.903 回答