Question

I'm opening up a database query from the Northwind database for each item that my ShoppingCart entails. It is to take ProductID and UnitsInStock out from the Products table. After I take the two columns out from the database to save the data into a DataTabel ds. Then I compare to make sure the quantity user entered is less than the column units in stock in the database.

theCart.Values is part of ICollections.

I am gettign error: from my exception message: "There was a problem connecting to the database: Object reference not set to an instance of an object."

Here's the code.

DataSet ds = new DataSet();
        OleDbConnection conn = new OleDbConnection((string)Application["DBConnectionString"]);
        foreach (OrderItem item in theCart.Values)
        {
            string selectionString =
            "SELECT Products.ProductID, Products.UnitsInStock " +
                "FROM Products" +
                "WHERE Products.ProductID = " + item.ProductID + ";";
            try
            {
                OleDbCommand cm = new OleDbCommand(selectionString, conn);
                OleDbDataAdapter da = new OleDbDataAdapter();
                da.SelectCommand = cm;
                da.Fill(ds);
                da.Dispose();
                 if (ds.Tables["Products"].Columns.Count != 0 &&
            ds.Tables["Products"].Rows.Count != 0)
            {
                for (int index = 0; index < ds.Tables["Products"].Rows.Count; index++)
                {
                    if (item.ProductID == int.Parse(ds.Tables["Products"].Rows[index][indexOfProductID].ToString()))
                    {
                        if (item.QuantityOrdered > int.Parse(ds.Tables["Products"].Rows[index][indexOfUnitsInStock].ToString()))
                        {
                            hasStock = false;
                            int inStock = int.Parse(ds.Tables["Products"].Rows[index][indexOfUnitsInStock].ToString());
                            txtUnderstockedItems.Text += "Sorry we do not have enough stock of item: " + item.ProductName +
                                "<br> Currently, " + item.ProductName + " (ID:" + item.ProductID + ") has " + inStock + " in stock.";
                        }
                        else
                        {//can output how many items in stock here. 
                            hasStock = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                txtUnderstockedItems.Text = "There was a problem connecting to the database: " + ex.Message;
            }
            finally
            {

                conn.Close();
            }


            }
        }
Was it helpful?

Solution

Rows or Columns is most likely null. Inspect ds prior to that if statement. A common reason something like this would happen is that the Products table returned nothing. You can't get the property of an object that does not exist, thus the exception. You should do a != null comparison instead of checking the count. If the length is zero the code inside the loop will never execute but you won't crash or anything.

if (ds.Tables["Products"].Columns != null && ds.Tables["Products"].Rows != null)

Just a heads up, this will cause no problems if your row count is zero, but you may need some logic within the loop to check that the columns you're planning to access exist.

OTHER TIPS

You are trying to get the table from the dataset with its hardcoded name as to what you see in the database, I just ran a test on a similar pattern and it looks like when you create a Dataset and fill it from the database as you are doing, the table name is not copied from the Database. As Tim suggested, you should check for ds.Table[0]

DataTableCollection.Item returns null if there's no table with the specified table-name.

If a command does not return any rows, no tables are added to the DataSet, and no exception is raised. So i assume that there's no table in the DataSet because no rows are returned.

I would initialize a single DatatTable manually instead and use the overload of Fill which takes a DataTable.

Dim table = new DataTable("Products")
da.Fill(table)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top