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();