sevynos
sevynos

Reputation: 57

return a datareader in c#

I'm trying to program a method to return a SQLiteDataReader object but without any success.

Here's the method's source code:

In a class file (DBUtils.cs):

public static SQLiteDataReader getAction(string dbPath, byte actionLevel)
{
    SQLiteConnection m_dbConnection;
    SQLiteDataReader reader = null;

    m_dbConnection = new SQLiteConnection("Data Source=" + dbPath + ";Version=3;FailIfMissing=True");
    m_dbConnection.Open();

    string sql = "SELECT * FROM Actions WHERE acLevel=" + actionLevel + " ORDER BY RANDOM() LIMIT 1";
    SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);

    reader = command.ExecuteReader(System.Data.CommandBehavior.CloseConnection);

    return reader;
}

In the MainWindow:

public MainWindow()
{
    InitializeComponent();

    const string dbPath = "../../TestDatabase.sqlite";

    SQLiteDataReader zReader = DBUtils.getAction(dbPath, 1);

    MessageBox.Show(Convert.ToString(zReader["acText"]));

}

Now, when I run step by step I do see that data has been loaded from the database when I'm in the getAction() method but when it comes back to the message box I get an Illegal Exception because there's no current row in the DataReader.

Anybody have a clue about what's happening?

Thanks

Upvotes: 0

Views: 860

Answers (3)

T McKeown
T McKeown

Reputation: 12847

You need to finish the reading process:

    public MainWindow()
    {
      ...
      using( SQLiteDataReader zReader = DBUtils.getAction(dbPath, 1))
      {
        if( rdr.Read() )
        {
          var someString = rdr.GetString(0);
          ...
        }
      }
    }

Upvotes: 1

sujith karivelil
sujith karivelil

Reputation: 29006

The DataReader always requires an open connection to read data from the Database, and you have to use Reader.Read method to get values from them, So you need to do small changes in your method signature like this:

public static SQLiteDataReader getAction(string dbPath, byte actionLevel)
{
   SQLiteDataReader reader = null;

   SQLiteConnection  m_dbConnection = new SQLiteConnection("Data Source=" + dbPath + ";Version=3;FailIfMissing=True");

    m_dbConnection.Open();

    string sql = "SELECT * FROM Actions WHERE acLevel=" + actionLevel + " ORDER BY RANDOM() LIMIT 1";
   SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection)   

    reader = command.ExecuteReader();
    return reader;  
}

And in the calling method these changes have to be applied:

SQLiteDataReader zReader = DBUtils.getAction(dbPath, 1);
while(zReader.Read())
{
    MessageBox.Show(zReader["acText"].ToString());
}

Upvotes: 0

Ivan Vargas
Ivan Vargas

Reputation: 703

You need to check if there are results before trying to fetch them. If you know for sure there is only one result, you can do

if(reader.Read())
{
  MessageBox.Show(Convert.ToString(zReader["acText"]));
}

If you expect multiple rows, do something like

while(reader.Read())
{
    // Code to read rows here
}

Upvotes: 0

Related Questions