I'm currently building a program which stores messages between users in a database and returns these messages to the user when the button below gets pressed. I'm using a SQL CE database using a OleDbConnection and using a DataReader.

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++;
    }
}

This code works for my Student class but when I reuse the code with minor changes within the Lecturer class the OledbDataReader says null, anyone know why?
Btw the values being returned aren't null the reader itself is null. Below is the non working code.

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]);
            }
    }
有帮助吗?

解决方案

Using Reflector:

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;
}

The CommandBehavior is default.the reader returned by this.ExecuteReaderInternal()---- >

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 wraps the new instance of OleDbDataReader, if it doesn't run the dataReader will be null.

The only way the reader is returned as null is if the internal RunExecuteReader method is passed 'false' for returnStream, which it isn't.

Here is the only place where this._executeQuery is set to false, but this one is not called in parallel because of Bid.ScopeEnter and Bid.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;
    }

Theoretically the data reader can be null if the query cannot be executed.

UPDATE: https://github.com/Microsoft/referencesource/blob/master/System.Data/System/Data/OleDb/OleDbCommand.cs#L658

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top