Three errors but yet everything looks normal

Lin100

Well-known member
Joined
Dec 12, 2022
Messages
69
Programming Experience
10+
I am trying to simulate a Dlookup function in MS Access where I want to retrieve just one column from
a record in an Access database. There are three errors. I have checked but everything looks normal to me.

Error CS1503 Argument 1: cannot convert from 'string' to 'Prop_Name' Line 25
Error CS0246 The type or namespace name 'Prop_Name' could not be found
(are you missing a using directive or an assembly reference?) Line 34
Error CS1001 Identifier expected Line 34

Lookup a column in an Access Database:
private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
         string Apartment_Status;
         DateTime Date_Reserved = DateTime.Today;
         MessageBox.Show("Date_Reserved =  " + Date_Reserved);

         object value = this.dataGridView2.CurrentRow.Cells[7].Value.ToString();
         if (value is DBNull) { return; }
         Apartment_Status = value.ToString();
         MessageBox.Show("Apartment_Status =  " + Apartment_Status);

         switch (Apartment_Status)
           {
              case "Reserved":
                  Reservation2 R2 = new Reservation2();
                  R2.Show();
              break;

              case "Vacant":
                  Reservation1 R1 = new Reservation1();
                  R1.Property_Name.Text = this.dataGridView2.CurrentRow.Cells[0].Value.ToString();
                  R1.Unit_Number.Text = this.dataGridView2.CurrentRow.Cells[1].Value.ToString();

                  string Prop_Name = R1.Property_Name.Text;
                  Obtain_Property_ID(Prop_Name);        Error  CS1503.  
                  R1.Show();
                break;

                default:
                break;
             }


 void Obtain_Property_ID(Prop_Name)        Error  CS0246,  Error  CS1001.
     {
          OleDbConnection con = new OleDbConnection();
          con.ConnectionString = ConfigurationManager.ConnectionStrings["Apartment_Management.Properties.Settings.AMS_2007ConnectionString"].ToString();
          con.Open();
          MessageBox.Show("Obtain_Property_ID procedure");
          OleDbCommand cmd = new OleDbCommand();
           
          String Prop_Name = "Modern Plano";
          cmd.CommandText = "SELECT Property_ID FROM Property WHERE Property_Name = '" + Prop_Name + "' ";

          cmd.Connection = con;
          OleDbDataAdapter da = new OleDbDataAdapter(cmd);
          DataSet ds = new DataSet();
          da.Fill(ds);
         
          var Property_ID = ds.Tables[0];
          MessageBox.Show("Property_ID " + Property_ID);
      }
 }
 
Last edited:
Change line 34 to:
void Obtain_Property_ID(string Prop_Name)

The problem is that the compiler thought that Prop_Name was a type, when you actually wanted it as the parameter name.
 
Not related to your problem, I wanted to point this out:
C#:
object value = this.dataGridView2.CurrentRow.Cells[7].Value.ToString();
if (value is DBNull) { return; }

The condition in the if statement will never be true because on the line above you forced value to be a string type by using ToString(). So it will never be of type DBNull. Recall that is compares types.
 
And when building on that. Since value is already a string, calling ToString() again on it in the next line after the if statement is pointless, other than to satisfy the compiler with regard to the assignment
 
I have corrected the code and it run without error. However, on line

var Property_ID = ds.Tables[0];
MessageBox.Show("Property_ID = " + Property_ID);

The result of MessageBox is Property_ID = Table. It suppose to be a number between 1 and 5. Here it looks like I am not using it correctly
because I am not familiar with ds.Tables[0]. Any suggestion you have would help.



Corrected Code:
 private void dataGridView2_CellContentClick(object sender, DataGridViewCellEventArgs e)
  {
     string Apartment_Status;
     DateTime Date_Reserved = DateTime.Today;
     MessageBox.Show("Date_Reserved =  " + Date_Reserved);

     object value = this.dataGridView2.CurrentRow.Cells[7].Value.ToString();

     Apartment_Status = value.ToString();
     MessageBox.Show("Apartment_Status =  " + Apartment_Status);

     switch (Apartment_Status)
       {
          case "Reserved":
            Reservation2 R2 = new Reservation2();
            R2.Show();
          break;

          case "Vacant":
            Reservation1 R1 = new Reservation1();
            R1.Property_Name.Text = this.dataGridView2.CurrentRow.Cells[0].Value.ToString();
            R1.Unit_Number.Text = this.dataGridView2.CurrentRow.Cells[1].Value.ToString();

            string Prop_Name = R1.Property_Name.Text;
            Obtain_Property_ID(Prop_Name);
            R1.Show();
          break;

          default:
          break;
       }

     void Obtain_Property_ID(string Prop_Name)
       {
          OleDbConnection con = new OleDbConnection();
          con.ConnectionString = ConfigurationManager.ConnectionStrings["Apartment_Management.Properties.Settings.AMS_2007ConnectionString"].ToString();
          con.Open();
          MessageBox.Show("Obtain_Property_ID procedure. Prop_Name =  " + Prop_Name);
          OleDbCommand cmd = new OleDbCommand();
           
          cmd.CommandText = "SELECT Property_ID FROM Property WHERE Property_Name = '" + Prop_Name + "' ";

          cmd.Connection = con;
          OleDbDataAdapter da = new OleDbDataAdapter(cmd);
          DataSet ds = new DataSet();
          da.Fill(ds);
           
          var Property_ID = ds.Tables[0];
          MessageBox.Show("Property_ID = " + Property_ID);     <<----- Property_ID = Table. It suppose to be a number between 1 and 5.
       }
  }
 
The result of MessageBox is Property_ID = Table. It suppose to be a number between 1 and 5.
In the .NET world, the default implementation of all objects's ToString() method is to just return the name of the type. Since each of the items in the Tables collection is a Table that is what is returned. C# is not like JavaScript or Python which will try to enumerate the contents of an object when you try get the string representation. You have to implement it yourself.
 
How would I enumerate the contents of an object ds.Tables[0] ?
would it be something like

var Property_ID = ds.Tables.CurrentRow.Cells[0];
 
Close. A Table won't have a CurrentRow property. But it does have all the rows exposed as a property named: Rows. It supports indexing just like the Cells (as well as the Rows on a DataGridView). And so you can index through all the rows that you want by passing in multiple index values. And for each Row that you get back, you can go through the columns by indexing through the Cells property like you have been doing.
 
I tried this and it gives me an error.
var Property_ID = ds.Tables.Rows[0].Cells[0];

Error CS1061 'DataTableCollection' does not contain a definition for 'Rows' and no accessible extension method 'Rows' accepting a first argument of type 'DataTableCollection' could be found
 
I got it.
var Property_ID = ds.Tables[0].Rows[0].ItemArray[0];

It is odd that Microsoft uses ItemArray to access a column.
They should be consistent and use column instead as in
var Property_ID = ds.Tables[0].Rows[0].Columns[0];
 
They do use column instead

var Property_ID = ds.Tables[0].Rows[0][0];

All this is an awful, ancient way of doing this data access though.. it's barely a step up from using a data reader. There are easier ways
 
@Lin100 : Sorry about pointing you to using Cells below the Row. I've not had to deal with Table since 2005. As @cjard said above, there are much better modern ways to deal with data coming back from a database.
 
Back
Top Bottom