2014-03-13 2 views
2

나는 현재 데이터베이스에 사용자간에 메시지를 저장하고 아래 버튼을 누르면됩니다 때 사용자에게 이러한 메시지를 반환하는 프로그램을 짓고 있어요. OleDbConnection을 사용하고 DataReader을 사용하는 SQL CE 데이터베이스를 사용하고 있습니다.방법 OleDbDataReader = null이

private void button3_Click(object sender, EventArgs e) 
{ 

    string [] lec_name = new string [10] ; 
    string [] content = new string [10] ; 
    string conn = "Provider=Microsoft.SQLSERVER.CE.OLEDB.3.5;Data Source=C:\\Users\\Leon\\Admin.sdf"; 
    OleDbConnection connection = new OleDbConnection(conn); 
    OleDbCommand command = connection.CreateCommand(); 
    command.CommandText = "SELECT * FROM Contact_DB WHERE Student_ID =" + iD + " AND Direction = '" + "To the student" + "'"; 

    try 
    { 
     connection.Open(); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("" + ex.Message); 
    } 

    OleDbDataReader reader = command.ExecuteReader(); 
    int up = 0; 
    int count = 0; 

    while (reader.Read()) 
    { 
     lec_name[up] = reader["Lecturer_Name"].ToString(); 
     content[up] = reader["Description"].ToString(); 
     up++; 
     MessageBox.Show("The lecturer " + lec_name[count] + " has messaged you saying :" + "\n" + content[count]); 
     count++; 
    } 
} 

이 코드는 내 Student 클래스 작동하지만 나는 OledbDataReader가 null 말한다 Lecturer 클래스 내에서 작은 변화와 코드를 재사용 할 때, 사람이 이유를 알고?
Btw 반환되는 값이 null이 아니므로 판독기 자체가 null입니다. 다음은 작동하지 않는 코드입니다.

private void button2_Click(object sender, EventArgs e) 
    { 
     string [] studentID = new string [10] ; 
     string [] content = new string [10] ; 
     string conn = "Provider=Microsoft.SQLSERVER.CE.OLEDB.3.5;Data Source=C:\\Users\\Leon\\Admin.sdf"; 
      OleDbConnection connection = new OleDbConnection(conn); 
      OleDbCommand command = connection.CreateCommand(); 
      command.CommandText = "SELECT * FROM Contact_DB WHERE Lecturer_Name =" + full + " AND Direction = '" + "To the lecturer" + "'"; 
      try 
      { 
       connection.Open(); 

      } 
      catch (Exception ex) 
      { 
       MessageBox.Show("" + ex.Message); 
      } 
      OleDbDataReader reader1 = command.ExecuteReader(); 
      int up = 0; 
      int count = 0; 
      while (reader1.Read()) 
      { 

       studentID[up] = reader1["Student_ID"].ToString(); 
       content[up] = reader1["Description"].ToString(); 
       up++; 

      } 
      MessageBox.Show("The student " + studentID[count] + " has messaged you saying :" + "\n" +content[count]); 
      } 
    } 
+0

예외가 있습니까? – Szymon

+2

게시 된 코드가 작동 코드입니까 아니면 작동하지 않는 코드입니까? 몇 가지 관찰 : 1. SQL 인젝션을 방지하기 위해 매개 변수화 된 쿼리를 배웁니다. 2. 연결을 열려고 시도하는 경우 예외가 발생하면 다른 모든 방법도 실패하므로 메서드를 종료해야합니다. 3.'using' 블록을 사용하거나 독자에게'Close()'를 호출하십시오. – Tim

+0

@Szymon yeah (토큰 라인 번호, Token line offset, Token in error ,,]) while (reader.Read()) 라인에서 중단 점을 사용할 때 datareader를 발견했습니다. null –

답변

1

사용 반사체 :

OleDbCommand.ExcuteReader :

public OleDbDataReader ExecuteReader(CommandBehavior behavior) 
{ 
OleDbDataReader reader; 
IntPtr ptr; 
OleDbConnection.ExecutePermission.Demand(); 
Bid.ScopeEnter(out ptr, "<oledb.OleDbCommand.ExecuteReader|API> %d#, behavior=%d{ds.CommandBehavior}\n", this.ObjectID, (int) behavior); 
try 
{ 
    this._executeQuery = true; 
    reader = this.ExecuteReaderInternal(behavior, "ExecuteReader"); 
} 
finally 
{ 
    Bid.ScopeLeave(ref ptr); 
} 
return reader; 
} 

CommandBehavior를가 this.ExecuteReaderInternal (의해 반환 default.the 리더 이다) ---->

private OleDbDataReader ExecuteReaderInternal(CommandBehavior behavior, string method) 
{ 
OleDbDataReader dataReader = null; 
OleDbException previous = null; 
int num2 = 0; 
try 
{ 
    object obj2; 
    int num; 
    this.ValidateConnectionAndTransaction(method); 
    if ((CommandBehavior.SingleRow & behavior) != CommandBehavior.Default) behavior |= CommandBehavior.SingleResult; 
    switch (this.CommandType) 
    { 
    case ((CommandType) 0): 
    case CommandType.Text: 
    case CommandType.StoredProcedure: 
     num = this.ExecuteCommand(behavior, out obj2); 
     break; 

    case CommandType.TableDirect: 
     num = this.ExecuteTableDirect(behavior, out obj2); 
     break; 

    default: 
     throw ADP.InvalidCommandType(this.CommandType); 
    } 
    if (this._executeQuery) 
    { 
     try 
     { 
      dataReader = new OleDbDataReader(this._connection, this, 0, this.commandBehavior); 
      switch (num) 
      { 
      case 0: 
       dataReader.InitializeIMultipleResults(obj2); 
       dataReader.NextResult(); 
       break; 

      case 1: 
       dataReader.InitializeIRowset(obj2, ChapterHandle.DB_NULL_HCHAPTER, this._recordsAffected); 
       dataReader.BuildMetaInfo(); 
       dataReader.HasRowsRead(); 
       break; 

      case 2: 
       dataReader.InitializeIRow(obj2, this._recordsAffected); 
       dataReader.BuildMetaInfo(); 
       break; 

      case 3: 
       if (!this._isPrepared) this.PrepareCommandText(2); 
       OleDbDataReader.GenerateSchemaTable(dataReader, this._icommandText, behavior); 
       break; 
      } 
      obj2 = null; 
      this._hasDataReader = true; 
      this._connection.AddWeakReference(dataReader, 2); 
      num2 = 1; 
      return dataReader; 
     } 
     finally 
     { 
      if (1 != num2) 
      { 
       this.canceling = true; 
       if (dataReader != null) 
       { 
        dataReader.Dispose(); 
        dataReader = null; 
       } 
      } 
     } 
    } 
    try 
    { 
     if (num == 0) 
     { 
      UnsafeNativeMethods.IMultipleResults imultipleResults = (UnsafeNativeMethods.IMultipleResults) obj2; 
      previous = OleDbDataReader.NextResults(imultipleResults, this._connection, this, out this._recordsAffected); 
     } 
    } 
    finally 
    { 
     try 
     { 
      if (obj2 != null) 
      { 
       Marshal.ReleaseComObject(obj2); 
       obj2 = null; 
      } 
      this.CloseFromDataReader(this.ParameterBindings); 
     } 
     catch (Exception exception3) 
     { 
      if (!ADP.IsCatchableExceptionType(exception3)) throw; 
      if (previous == null) throw; 
      previous = new OleDbException(previous, exception3); 
     } 
    } 
} 
finally 
{ 
    try 
    { 
     if (dataReader == null && 1 != num2) this.ParameterCleanup(); 
    } 
    catch (Exception exception2) 
    { 
     if (!ADP.IsCatchableExceptionType(exception2)) throw; 
     if (previous == null) throw; 
     previous = new OleDbException(previous, exception2); 
    } 
    if (previous != null) throw previous; 
} 
return dataReader; 
} 

this._executeQuery은 012의 새 인스턴스를 래핑합니다., 실행하지 않으면 dataReadernull이됩니다. 내부 RunExecuteReader 방법 그렇지 returnStream 위해 'false'로 전달되는 경우

리더가 null로 리턴하는 유일한 방법이다.

여기 this._executeQueryfalse로 설정되어있는 유일한 장소이지만,이 일 때문에 Bid.ScopeEnterBid.ScopeLeave의 병렬로 호출되지 않습니다.

public override int ExecuteNonQuery() 
    { 
     int num; 
     IntPtr ptr; 
     OleDbConnection.ExecutePermission.Demand(); 
     Bid.ScopeEnter(out ptr, "<oledb.OleDbCommand.ExecuteNonQuery|API> %d#\n", this.ObjectID); 
     try 
     { 
      this._executeQuery = false; 
      this.ExecuteReaderInternal(CommandBehavior.Default, "ExecuteNonQuery"); 
      num = ADP.IntPtrToInt32(this._recordsAffected); 
     } 
     finally 
     { 
      Bid.ScopeLeave(ref ptr); 
     } 
     return num; 
    } 

이론적으로 데이터 판독기는 쿼리를 실행할 수없는 경우 null 일 수 있습니다.

+0

은 어쨌든 당신이, 내가 아주 초보 프로그래머에게 –

+0

감사 해요 제발 더 자세하게 설명 할 수 있나요 많이, 그게 말이 되네, 투표 할 수 없어 미안해. 내 평판이 낮다. –

+0

다행히도 도움이된다. 좀 더 자세한 내용으로 대답을 업데이트한다. .NET 리플렉터를 사용하여 구현 방법을 확인했다. –