2011-09-08 93 views
1

我需要确定由ExecuteReader返回的结果集的结构。我使用以下方法:在Ado.Net中,我可以确定结果集中的列是否可以为空?

public List<NameAndType> ResultSetStructure(DataTable columns) 
    { 
     var ret = new List<NameAndType>(); 
     foreach (DataRow column in columns.Rows) 
     { 
      ret.Add(new NameAndType { Name = column[NameIndex].ToString(), 
              Type = column[TypeIndex].ToString() 
      }); 
     } 
     return ret; 
    } 

(SNIP)

using (SqlDataReader dr = command.ExecuteReader()) 
     { 

      var rawColumns = dr.GetSchemaTable(); 
      var columns = ResultSetStructure(rawColumns); 

这给我列名和类型,但我也想知道,如果列可以为空,这样我才知道这以下选项可供选择:

decimal density = dr.GetDecimal(0); 
decimal? density = dr.IsDBNull(0) ? (decimal?)null : dr.GetDecimal(0); 

我可以做到吗? TIA。

编辑:我刚刚发现我所需要的:

column[13].ToString() 
+1

德纳里有更容易的方式来做到这一点(新的元数据发现的DMV)。但为什么不只是总是假定为无效的?如果列不是NULLable,那么只会有条件的一边运行。 –

+0

@Aaron Bertrand这是一个很好的策略,但问题在于您希望客户端匹配约束,以便消费者知道他们是否可以有效地将属性设置为NULL。你是对的,它不是你想要在运行时决定的那种东西,你真的希望它在编译时决定,所以在运行时检查并不能帮助你。对于一个完全动态的东西 - 你必须假设为空。 –

+0

@Cade我建议如果你想让客户端匹配,你可以设计客户端与数据库约束。在运行时检查它(并在客户端建立响应验证)会变得非常快,非常快。 :-) –

回答

0

下面的代码能够完成任务:

  ret.Add(new NameAndType { Name = column[NameIndex].ToString(), 
              Type = column[TypeIndex].ToString(), 
              IsNullable = column[13].ToString().Equals("True") 
0

我想有知道列是否可为空或不是没有这样的方式。你可以尝试写下如下所示的扩展方法:

 public static decimal GetDecimal(this SqlDataReader reader, int columnIndex) 
    {  
     if(!reader.IsDBNull(columnIndex)) 
      {  
      return reader.GetDecimal(colIndex);  
      } 
     else 
      { 
        return 0; 
     } 
     } 

希望这会有所帮助!

相关问题