22

I was trying to add data from a database to a ComboBox.

try
{
    SqlCeCommand com = new SqlCeCommand("select * from Category_Master", con);
    SqlCeDataReader dr = com.ExecuteReader();

    while(dr.Read())
    {
        string name = dr.GetString(1);
        cmbProductCategory.Items.Add(name);
    }
}
catch(Exception ex)
{
    System.Windows.Forms.MessageBox.Show(ex.Message, System.Windows.Forms.Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}

I get the following exception:

Unable to cast object of type 'System.Int32' to type 'System.String'

What am I missing here?

10
  • 4
    What exception are you getting ?? try to use Convert.ToString(value) rather the value.ToString() Commented Oct 25, 2013 at 6:08
  • Unable to cast object of type 'System.Int32' to type 'System.String'. Commented Oct 25, 2013 at 6:09
  • 1
    Try selecting just the column you want, using * may very well end up getting the wrong column if someone changes the database schema later. I suspect you're not getting the column you're expecting, but an int column that is at that position. Commented Oct 25, 2013 at 6:13
  • 2
    Obviously, data reader's column with index 1 has a value, which type is System.Int32, not a System.String. Commented Oct 25, 2013 at 6:13
  • 3
    Why are you selecting all columns when you're only reading one of them? Just select the column you want - that will cut down on the possibilities of error to start with. Commented Oct 25, 2013 at 6:15

6 Answers 6

33

Your column doesn't have the type string. Apparently it's int. So use:

dr.getInt32(1).ToString()

or even

dr.GetValue(1).ToString()

which should be more roubst to type changes in the database.

As some sort of general advice I try to follow at least:

  • Select only what you need. This has mostly performance reasons and the reason that you have to state the column names explicitly, thereby getting at least a sensible error if you change your schema incompatibly.
  • Access the fields using their names, e.g.

    dr.GetGuid(dr.GetOrdinal("id"))
    

    Such a thing can also be nicely solved by an extension method:

    public T GetFieldValue<T>(this DbDataReader reader, string columnName)
    {
        return reader.GetFieldValue<T>(reader.GetOrdinal(columnName));
    }
    

Side note: Including stack traces (or at least saying which line in your code the exception comes from) can be helpful to others trying to help you. As you can see from the wild guesses what the culprit could be. My guess would be that the stack trace looks somewhat like this:

SqlDataReader.GetString
YourCode.YourMethod

and that GetString looks more or less like this:

public string GetString(int index)
{
    return (string) GetValue(index);
}
Sign up to request clarification or add additional context in comments.

7 Comments

@AndreasNiedermair Yes it is zero-based. That's why, when you say GetString(1), it search on second column in his table.
yes, first column is ID and second column is CategoryName which in nvarchar
Exception is at this line, i checked. "string name = dr.GetString(1);"
when you are talking about robustness, you should also consider a reader.IsDBNull(int ordinal)-check before accessing it with an ordinal!
... ;) nevertheless, such small hints would vastly reduce the pitfalls, the OP might have to deal with ...
|
2

Your column doesn't seem to have type int. To avoid things like this, you can use the columnnames instead of indexes.

try
{
    SqlCeCommand com = new SqlCeCommand("select * from Category_Master", con);
    SqlCeDataReader dr = com.ExecuteReader();
    while(dr.Read()){
        string name = dr["yourColumnName"].ToString();
        cmbProductCategory.Items.Add(name);
    }
}
catch(Exception ex)
{
    System.Windows.Forms.MessageBox.Show(ex.Message, System.Windows.Forms.Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}

4 Comments

that's not a valid reason!! with ordinal you can do typed things, like GetString, GetInt32... with the string-indexer you can access the object (untyped) value
Correct, but at least you know for sure which column you're addressing.
still no valid reason... reader.GetOrdinal("myColumn") gives an ordinal for the column i want to deal with - how can you be more explicit?!
@AndreasNiedermair Point taken.
2

you can try the following conversion:

  Convert.ToInt32(yourstring)

Comments

1

If you are encountering the error "Unable to cast object of type 'System.Int32' to type 'System.String'" after upgrading your project and previously used a value conversion like this:

.HasConversion(
    v => v.ToString(),
    v => int.Parse(v)
);

This might have worked in earlier versions of EF Core but may cause issues in later versions, such as .NET 8.

A simpler and more reliable approach is to use .HasConversion(), which allows EF Core to handle the type conversion more effectively. For example:

builder.Entity<SomeEntity>(entry =>
{
    entry.ToTable("MyTable")
        .HasKey(c => c.MyPrimaryKey);
        
    entry.Property(c => c.MyPrimaryKey)
        .HasMaxLength(255)
        .HasColumnName("ID")
        .HasConversion<int>();
});

This approach resolves the type conversion issue and is more straightforward.

Comments

0

Ok OK. Its solved....

Here is the code..

        try
        {
            SqlCeCommand com = new SqlCeCommand("select CategoryName from Category_Master", con);
            SqlCeDataReader dr = com.ExecuteReader();
            while(dr.Read()){
                string name = dr.GetString(0);
                cmbProductCategory.Items.Add(name);
            }
        }
        catch(Exception ex)
        {
            System.Windows.Forms.MessageBox.Show(ex.Message, System.Windows.Forms.Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

I changed the sqlcommand to a single value and changed column number for dr.getstring() to 0.. it worked. Thank you guys for the help.. I expect more because i am only half way in my project..

Comments

0

Use Column name in your query then specify that column name into the reader.

SqlCeCommand com = new SqlCeCommand("select catg from Category_Master", con);
                SqlCeDataReader dr = com.ExecuteReader();
                while(dr.Read()){
                    string name = dr("catg").ToString();
                    cmbProductCategory.Items.Add(name);
                }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.