2017-06-14 59 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);