2014-04-03 5 views
2

저는 C#에 대해 아직 아주 익숙해 져 있으므로 제발 저와 함께하시기 바랍니다. 다음과 같은 표가있는 Access 데이터베이스가 있습니다.SetField는 DBNull.Value를 System.Int32로 변환 할 수 없습니다.

ID1 ID2  Name 
---------------------- 
1111 1234567 Joe 
2222 1234567 Patricia 
3333 7654321 Laurie 

필드에 Null 값이 없습니다. 각 열 값의 가장 긴 텍스트 표현의 길이를 DataTable에 저장하려고합니다.

public DataTable GetMetadata(string tableName) 
{ 
    ... 

    // My OLEDB connection _oleConnection is already open 

    OleDbCommand selectTable = new OleDbCommand("SELECT * FROM [" + 
     tableName + "]", _oleConnection); 

    OleDbDataReader oleReader = selectTable.ExecuteReader(); 

    DataTable schemaTable = oleReader.GetSchemaTable().Copy(); 
    schemaTable.Columns.Add("_maxCharLength", typeof(int)); 

    foreach (DataRow schemaRow in schemaTable.Rows) 
    { 
     OleDbCommand getMax = new OleDbCommand(); 
     getMax.Connection = _oleConnection; 

     // Convert non-text fields to strings before getting lengths 

     if (schemaRow.Field<Type>("DataType") == typeof(string)) 
     { 
      getMax.CommandText = "SELECT MAX(LEN(" + 
       schemaRow.Field<string>("ColumnName") + ")) FROM " + 
       tableName; 
     } 
     else 
     { 
      getMax.CommandText = "SELECT MAX(LEN(STR(" + 
       schemaRow.Field<string>("ColumnName") + "))) FROM " + 
       tableName; 
     } 

     int maxCharLength = ConvertFromDBVal<int>(getMax.ExecuteScalar()); 

     schemaRow.SetField(schemaRow.Field<int>("_maxCharLength"), 
      maxCharLength); 

     getMax.Dispose(); 
     getMax = null; 
    } 

    ... 

    return schemaTable; 
} 
디버거 미친 얻을

schemaRow.SetField(...)에서 다음과 같이 말한다 : 다음과 같이 나는 테이블에서 데이터를 얻을 수

public static T ConvertFromDBVal<T>(object obj) 
{ 
    if (obj == null || Convert.IsDBNull(obj)) 
     return default(T); 
    else 
     return (T)obj; 
} 

: this similar question에 고삐의 답변에 따라

, 나는이 편리한 일반적인 기능을 포함 :

Cannot cast DBNull.Value to type 'System.Int32'. Please use a nullable type. 

그래서 nullable 유형. 나는 디버거가

DataSet does not support System.Nullable<>. 

그래서 내가 int로 다시 변경 말한다 다음
schemaTable.Columns.Add("_maxCharLength", typeof(int?)); // was typeof(int) 

를 교체했다.

Console.WriteLine("{0}, {1}, {2}, {3}", 
    tableName, 
    schemaRow.Field<string>("ColumnName"), 
    maxCharLength, 
    maxCharLength.GetType()); 

이 전혀 문제없이 작동합니다 : 어떤 null 값을 변환하는 기능을 사용하더라도 다음과 같이 나는 foreach 루프의 값과 그 유형을 확인. 콘솔에서 다음과 같이 표시됩니다.

Table1, ID1, 4, System.Int32 
Table1, ID2, 7, System.Int32 
Table1, Name, 8, System.Int32 

null 값도 예외도 아닙니다. 모든 것이 예상대로입니다. 그러면 에 그 값을 넣지 않는 이유는 무엇입니까?

답변

2

난 당신이

schemaRow.SetField("_maxCharLength", maxCharLength); 

DataRow.SetField 연장 첫 번째 매개 변수에 대한 열의 이름 또는 열 수집 또는 DataColumn에 내부 열의 서수 위치를 필요로 SetField의 라인을 변경할 필요가 있다고 생각 예.

오류 메시지는 DataRow.Field<T> 확장명을 사용하여 _ maxCharLength 필드의 값을 읽으려고한다는 사실 때문에 발생합니다. 그러나 코드의 시점에서 아직 값을 설정하지 않았기 때문에 _maxCharLength 필드는 여전히 null입니다.

논리적 인 관점에서 SetField 확장의 유효한 오버로드를 호출하기 때문에 컴파일러에서이 오류에 대해 경고 할 수 없습니다. 값을 설정하기 위해 열의 서수 위치를 나타 내기 위해 정수가 필요한 것.

+0

완벽하게 작동합니다. 분명히 필자는 필자가 가지고있는 문서를 철저히 읽지 않았다. 첫 번째 매개 변수가 'DataColumn'이라고 생각했습니다. 어쨌든, 고마워요 !! –