简体   繁体   English

在C#中从SQL处理Null类型

[英]Handling Null types from SQL in C#

I am using the SqlDataReader to get values from an SQL table and assign them to their respective variables. 我使用SqlDataReader从SQL表中获取值并将它们分配给它们各自的变量。 But in my table, int and double type columns have null values. 但在我的表中, intdouble类型列具有空值。 So when I try to read a null int and assign it to an int variable, it crashes. 因此,当我尝试读取null int并将其分配给int变量时,它会崩溃。

Here is how the values are being assigned to: 以下是将值分配给的方式:

public int ID { get; set; }
public int Map { get; set; }
public int TypeID { get; set; }

And this is where they are being read: 这是他们正在阅读的地方:

while (objSqlDataReader.Read())
{
    data= new data();
    emissiondata.ID = (int)objSqlDataReader["EFID"];
    emissiondata.Map = (int)objSqlDataReader["EFMappingID"];
    emissiondata.TypeID =(SqlInt32)objSqlDataReader["MobileTypeID"];

So if any of these is null , even when i'm debugging it, it crashes and doesn't continue. 因此,如果其中任何一个为null ,即使我正在调试它,它也会崩溃并且不会继续。 How do I handle the null values in SQL and how do I assign empty values to my int if it is null ? 如何处理null在SQL价值观和我怎么分配空值到我的int ,如果它是null

So, to find a possible answer I look at the documentation for the class you're talking about: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.aspx There's a IsDBNull method. 所以,为了找到一个可能的答案,我看看你正在谈论的类的文档: http//msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.aspx有一个IsDBNull方法。 Not having C# around, this should work: 没有C#,这应该工作:

while (objSqlDataReader.Read())
{
   data= new data();
   if (!objSqlDataReader.IsDBNull(objSqlDataReader.GetOrdinal("EFID")))
   {
      emissiondata.ID = (int)objSqlDataReader["EFID"];
   } else {
      // Whatever you want to do when it is null
   }
   if (!objSqlDataReader.IsDBNull(objSqlDataReader.GetOrdinal("EFMappingID")))
   {
      emissiondata.Map = (int)objSqlDataReader["EFMappingID"];
   } else {
      // Whatever you want to do when it is null
   }
   if (!objSqlDataReader.IsDBNull(objSqlDataReader.GetOrdinal("MobileTypeID")))
   {
      emissiondata.TypeID = (int)objSqlDataReader["MobileTypeID"];
   } else {
      // Whatever you want to do when it is null
   }
}

Can't test it now but you can try with int? 现在无法测试,但您可以尝试使用int? , the nullable int . ,可空的int It's a shorthand for Nullable<Int32> . 它是Nullable<Int32>的简写。 If objSqlDataReader can be cast to int? 如果objSqlDataReader可以转换为int? , change your fields to int? ,将您的字段更改为int? and add extra logic to property setter if you have to do something when value is null. 如果在null为null时必须执行某些操作,请向属性setter添加额外的逻辑。

DBNull.Value works on DataTable rows, I'm not sure with SqlDataReader: DBNull.Value适用于DataTable行,我不确定SqlDataReader:

bool isNull = objSqlDataReader.GetOrdinal("EFID") == DBNull.Value;

If you use SqlDataReader's GetSqlInt32,GetSqlDateTime, etc for example, they are null-aware out-of-the-box. 例如,如果您使用SqlDataReader的GetSqlInt32,GetSqlDateTime等 ,则它们是开箱即用的空值。

Instead of unboxing: 而不是拆箱:

emissiondata.ID = (int)objSqlDataReader["EFID"];

You do this instead: 你这样做:

SqlInt32 emissionId = objSqlDataReader.GetSqlInt32(emissionIdOrdinal);

Then you can test for null directly: 然后你可以直接测试null:

if (emissionId.IsNull) ...

However, those methods need the column's ordinal to access value. 但是,这些方法需要列的序数来访问值。 You can setup those ordinals before your loop 您可以在循环之前设置这些序数

int emissionIdOrdinal = rdr.GetOrdinal("EFID");

But if you really want C#'s null, you make a helper function for it instead: 但是如果你真的想要C#的null,你可以为它做一个辅助函数:

public static int? ToNullable(this SqlInt32 value)
{
    return value.IsNull ? (int?) null : value.Value;
}

To access it with your nullable variable: 要使用可空变量访问它:

int? emissionId = objSqlDataReader.GetSqlInt32(emissionIdOrdinal).ToNullable();

You can now test null directly: 您现在可以直接测试null:

if (emissionId == null)

An advice, try to change your class' properties to nullable types, precluding the need for you to use another variable: 建议,尝试将类的属性更改为可空类型,从而无需使用其他变量:

public int? ID { get; set; }
public int? Map { get; set; }
public int? TypeID { get; set; }

Final code: 最终代码:

data= new data();
emissiondata.ID = objSqlDataReader.GetSqlInt32(emissionIdOrdinal).ToNullable();
emissiondata.Map = objSqlDataReader.GetSqlInt32(emissionMapOrdinal).ToNullable();

You could do this in the query itself. 您可以在查询本身中执行此操作。 In Oracle, the function is NVL() . 在Oracle中,该函数是NVL() Looks like you're using MS Sql Server, which uses: 看起来你正在使用MS Sql Server,它使用:

ISNULL(YOUR_FIELD,0)

Usage and syntax for other RDBMS is here: http://www.w3schools.com/sql/sql_isnull.asp 其他RDBMS的用法和语法如下: http//www.w3schools.com/sql/sql_isnull.asp

I realize this is old, but if you are needing this answer after 2016-07-14: When SQL Type is int, null Use int? 我意识到这是旧的,但是如果你在2016-07-14之后需要这个答案:当SQL Type是int时,null使用int? as the data type. 作为数据类型。

int? 诠释? is a "nullable" int - so when SQL returns NULL for a column, the property value receives the value null. 是一个“可为空”的int - 所以当SQL为列返回NULL时,属性值接收值null。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM