2017-06-14 56 views
0

我有以下表格:如何处理这个NULL数据?

CREATE TABLE [dbo].[CATEGORIE](
    [bijdrage_id] [int] NOT NULL, 
    [categorie_id] [int] NULL, 
    [naam] [nvarchar](255) NOT NULL,) 

我用这个查询检索数据:

select c.bijdrage_id, c.categorie_id AS Subcategorievan, c.Naam from CATEGORIE as c 

随着下面的C#代码,我把我所有的值到Categorie对象:

public List<Categorie> geefAlleCategorien() 
     { 
      List<Categorie> categorien = new List<Categorie>(); 
      string query = "select c.bijdrage_id, c.categorie_id as SubCategorieVan, c.Naam from CATEGORIE as c"; 
      SqlDataReader reader = db.Select(query); 
      while (reader.Read()) 
      { 
       Categorie c = new Categorie(); 
       c.Id = reader.GetInt32(0); 
       c.SubCategorieVan = reader.GetString(1); 
       c.Naam = reader.GetString(2); 
       categorien.Add(c); 
      } 
      db.Close(); 
      return categorien; 
     } 

我的问题是,“categorie_id”列中的某些值为NULL,“reader.GetString(1)”方法无法处理NULL值。

如何处理这些NULL值与我的C#代码?

+2

使用'ISNULL()'在SQL码。 'isnull(c.categorie_id,'')'将用空格替换它。或者...在你的表定义中使它不为NULL;) – scsimon

+1

'categorie_id'是一个'int',而不是'string' – Amy

+1

只从catagory_id不为空的数据库返回行。 – DaImTo

回答

3

您可以使用IsDBNull

Categorie c = new Categorie(); 
c.Id = reader.GetInt32(0); 
c.SubCategorieVan = reader.IsDBNull(1) ? null : reader.GetString(1); 
c.Naam = reader.GetString(2); 
categorien.Add(c); 
+0

当你在查询中可以完成@ DB层并且可能是最清洁的解决方案时,在应用程序代码中执行此检查实际上没有必要执行此操作 – Rahul

+0

@Rahul:什么意思_unnecessary_?在应用程序层执行此操作时没有任何开销,并且OP明确要求:“我怎样才能用我的** c#代码处理这些NULL值?”_ –

+0

好吧,没有必要不是因为没有开销但这样做没有意义。关于OP ...查看他的最后评论*我最后在查询中使用了ISNULL()方法。这给了我最清洁的解决方案* – Rahul

3

那么你可以在SQL中使用COALESCE()功能,并返回像

select c.bijdrage_id, 
coalesce(c.categorie_id,0) AS Subcategorievan, 
c.Naam 
from CATEGORIE as c 
+0

_“如何处理这些空值与我的C#代码?”_ –

+2

@TimSchmelter,是的,但没有必要在应用程序代码中处理它。相反,这是一个数据库操作,应该卸载到DB – Rahul

+0

为什么?在应用程序层执行此操作时没有任何开销:_“我如何使用我的** c#代码处理这些'NULL'值”# –

1

的问题是一个默认值,null在数据库中不返回一个C#null,但一个DbNull.Value。如果返回了c#null,则所有引用类型(但不是所有值类型)都会解决该问题。因此,当数据库中的列可为空时,您必须检查DbNull.Value

你有serveral的选项:使用SqlDataReader.IsDbNull(...)

  • 测试。
  • 使用as算子结合SqlDataReader.GetValue(...)进行测试。这只适用于可空类型。

例子:

c.SubCategorieVan = reader.IsDbNull(1) ? null : reader.GetString(1); 

c.SubCategorieVan = reader.GetValue(1) as string; 

或者......如果你想给你的属性的默认值,则返回DBNull的时候,你可以给一个默认值在您的代码中:

c.SubCategorieVan = reader.IsDbNull(1) ? "Leeg" : reader.GetString(1); 

c.SubCategorieVan = reader.GetValue(1) as string ?? "Leeg"; 

您可以创建一个扩展方法:

static public T GetValue<T>(this IDataReader reader, int columnIndex, T defaultValue = default(T)) 
{ 
    return reader.IsDbNull(columnIndex) ? defaultValue : (T)reader.GetValue(columnIndex) 
} 

这样一来,你的阅读方法有可能成为非常干净:

c.Id = reader.GetValue<int>(0); 
c.SubCategorieVan = reader.GetValue<string>(1, "Leeg"); // In case you want to use this default value. 
c.Naam = reader.GetValue<string>(2); 
0

一切皆与扩展方法更好....
这里是一个小宝石,我很久以前发现在互联网上的某个地方:

public static class IDataReaderExtensions 
{ 
    public static T GetValueOrDefault<T>(this IDataReader reader, int index) 
    { 
     return (Convert.IsDBNull(reader[index])) ? default(T) : (T)reader.GetValue(index); 
    } 

    public static T GetValueOrDefault<T>(this IDataReader reader, string name) 
    { 
     return reader.GetValueOrDefault<T>(reader.GetOrdinal(name)); 
    } 
} 

然后你使用这样的:

c.SubCategorieVan = reader.GetValueOrDefault<int>(1);