c# - SqlDataReader 对象的内联空检查

标签 c# sql null nullable

我正在尝试构建一种查询 SQL 表并将找到的值分配给新对象列表的方法。这是它如何工作的一个简单示例(假设阅读器和连接已设置并正常工作):

List<MyObject> results = new List<MyObject>();
int oProductID = reader.GetOrdinal("ProductID");
int oProductName = reader.GetOrdinal("ProductName");

while (reader.Read())
{
    results.Add(new MyProduct() {
        ProductID = reader.GetInt32(oProductID),
        ProductName = reader.GetString(oProductName)
    });
}

还有大约 40 个其他属性,所有MyObject 中都可以为 null定义,所以我尽量让作业保持整洁。问题是我需要在读取器返回 null 的任何地方为对象分配 null 值。上面代码中,如果读取器抛出“Data is Null”异常。我知道可以使用 if检查 DbNull 的语句首先,但由于有这么多属性,我希望通过不必拼出 if 来使代码更简洁。每个属性的声明。

一些搜索让我找到了 null-coalescing运算符,它似乎应该完全按照我的意愿行事。所以我尝试将分配更改为如下所示:

ProductID = reader.GetInt32(oProductID) ?? null,
ProductName = reader.GetString(oProductName) ?? null

这适用于任何 string但给了我 Operator '??' cannot be applied to operands of type 'int' and '<null>' 的错误(或除 string 之外的任何其他数据类型。我特别指出 int (以及其他所有内容)在对象定义中可以为空,但这里它告诉我它不能这样做。

问题

在这种情况下,有没有一种方法可以处理空值:(1) 清楚地写在行内(以避免每个属性单独的 if 语句),以及 ( 2) 使用任何数据类型?

最佳答案

数据库中的 Null 不是“null”,而是 DbNull.Value。 ??和 ?。在这种情况下,运营商将无法工作。 GetInt32 等如果数据库中的值为 null 将抛出异常。我做了一个通用方法并保持简单:

T SafeDBReader<T>(SqlReader reader, string columnName)
{
   object o = reader[columnName];

   if (o == DBNull.Value)
   {
      // need to decide what behavior you want here
   }

   return (T)o;
}

例如,如果您的数据库具有可为空的整数,则您无法将它们读入整数,除非您想默认为 0 或类似值。对于可空类型,您可以只返回 null 或 default(T)。

Shannon 的解决方案既过于复杂,又会成为性能问题(大量过度反射)IMO。

关于c# - SqlDataReader 对象的内联空检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39259918/

相关文章:

C#:如何将 null 传递给需要 ref 的函数?

c# - 在 Ravendb 文档中查询子集合

c# - 如何修复错误 : The message received from the server could not be parsed

c# - 方法没有重载,需要 0 个参数?

mysql - SQL触发器,插入语句

sql - 排序联合但保持不同

python - pyodbc - 在哪里插入数据?

检查指针是否为 NULL 会导致段错误

C# 和继承。对象为扩展类对象时基类属性为null

mysql - 带有 NULL 的 SQL CASE 语句