[C#] SQL 데이터 리더-널 열 값 처리

SQLdatareader를 사용하여 데이터베이스에서 POCO를 작성하고 있습니다. 데이터베이스에서 null 값을 발견 한 경우를 제외하고 코드가 작동합니다. 예를 들어, 데이터베이스의 FirstName 열에 null 값이 포함되어 있으면 예외가 발생합니다.

employee.FirstName = sqlreader.GetString(indexFirstName);

이 상황에서 null 값을 처리하는 가장 좋은 방법은 무엇입니까?



답변

다음을 확인해야합니다 IsDBNull.

if(!SqlReader.IsDBNull(indexFirstName))
{
  employee.FirstName = sqlreader.GetString(indexFirstName);
}

이것이이 상황을 감지하고 처리 할 수있는 유일한 방법입니다.

나는 그 것들을 확장 메소드에 싸서 열이 실제로 있다면 기본값을 반환하는 경향이 있습니다 null.

public static string SafeGetString(this SqlDataReader reader, int colIndex)
{
   if(!reader.IsDBNull(colIndex))
       return reader.GetString(colIndex);
   return string.Empty;
}

이제 다음과 같이 호출 할 수 있습니다.

employee.FirstName = SqlReader.SafeGetString(indexFirstName);

예외 또는 null값에 대해 다시 걱정할 필요가 없습니다 .


답변

기본값 as과 함께 ??연산자를 연산자 와 결합하여 사용해야 합니다. 값 유형은 널 입력 가능으로 읽고 기본값이 제공되어야합니다.

employee.FirstName = sqlreader[indexFirstName] as string;
employee.Age = sqlreader[indexAge] as int? ?? default(int);

as운영자는 DBNull이에 대한 검사를 포함하여 캐스팅을 처리합니다.


답변

문자열의 경우 간단히 객체 버전 (배열 연산자를 사용하여 액세스)을 캐스트하고 널 (null) 문자열에 널 (null)을 입력하면됩니다.

employee.FirstName = (string)sqlreader[indexFirstName];

또는

employee.FirstName = sqlreader[indexFirstName] as string;

정수의 경우 nullable int로 캐스팅하면 GetValueOrDefault ()를 사용할 수 있습니다

employee.Age = (sqlreader[indexAge] as int?).GetValueOrDefault();

또는 null 병합 연산자 (?? ).

employee.Age = (sqlreader[indexAge] as int?) ?? 0;


답변

IsDbNull(int)일반적으로와 같은 방법을 사용 GetSqlDateTime하고 비교하는 것보다 훨씬 느립니다 DBNull.Value. 에 대한 이러한 확장 방법을 사용해보십시오 SqlDataReader.

public static T Def<T>(this SqlDataReader r, int ord)
{
    var t = r.GetSqlValue(ord);
    if (t == DBNull.Value) return default(T);
    return ((INullable)t).IsNull ? default(T) : (T)t;
}

public static T? Val<T>(this SqlDataReader r, int ord) where T:struct
{
    var t = r.GetSqlValue(ord);
    if (t == DBNull.Value) return null;
    return ((INullable)t).IsNull ? (T?)null : (T)t;
}

public static T Ref<T>(this SqlDataReader r, int ord) where T : class
{
    var t = r.GetSqlValue(ord);
    if (t == DBNull.Value) return null;
    return ((INullable)t).IsNull ? null : (T)t;
}

다음과 같이 사용하십시오.

var dd = r.Val<DateTime>(ords[4]);
var ii = r.Def<int>(ords[0]);
int nn = r.Def<int>(ords[0]);


답변

이를 수행하는 한 가지 방법은 db null을 확인하는 것입니다.

employee.FirstName = (sqlreader.IsDBNull(indexFirstName)
    ? ""
    : sqlreader.GetString(indexFirstName));


답변

reader.IsDbNull(ColumnIndex) 많은 답변이 말한대로 작동합니다.

그리고 열 이름으로 작업하는 경우 유형을 비교하는 것이 더 편할 수 있습니다.

if(reader["TeacherImage"].GetType() == typeof(DBNull)) { //logic }


답변

NULL 이 없다고 생각 합니다.열 이름을 사용하여 데이터 리더 내에서 행이 반환되면 열 값 .

그렇게 datareader["columnName"].ToString();하면 항상 빈 문자열이 될 수있는 값을 제공합니다 (String.Empty 비교 해야하는 경우).

나는 다음을 사용하고 너무 걱정하지 않을 것입니다 :

employee.FirstName = sqlreader["columnNameForFirstName"].ToString();