2014-03-13 51 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類,但是當我再次使用LecturerOledbDataReader說空內的微小變化的代碼,任何人都知道爲什麼嗎?
Btw所返回的值不爲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.在閱讀器上使用'use'塊或調用'Close()'。 – Tim

+0

@Szymon是啊(解析查詢時出現錯誤[令牌行號,令牌行偏移量,令牌錯誤,,])但是,當while(reader.Read())行使用斷點時,我發現數據讀取器一片空白。 –

回答

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的新實例,如果不運行dataReader將會是null

讀者返回爲null的唯一方法是如果內部RunExecuteReader方法爲returnStream傳遞'false',則不是。

這裏是唯一的地方,其中this._executeQuery設置爲false,但這個並不是因爲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; 
    } 

理論上的數據讀取器可以爲空,如果查詢不能被執行。

+0

是否可以,你可以更詳細地解釋這個問題,我是一個新手程序員 –

+0

謝謝很多,它是有道理的,對不起,我不能投票。我的名譽很低。 –

+0

很高興幫助。我用更多的細節更新了答案。我使用.NET REFLECTOR來了解如何實現。 –