C# 无法在 DataReader.GetString() 中将“System.Int32”类型的对象转换为“System.String”类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19582256/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 15:21:25  来源:igfitidea点击:

Unable to cast object of type 'System.Int32' to type 'System.String' in DataReader.GetString()

c#sqldatareader

提问by Kamal

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

我试图将数据从数据库添加到 acombobox。

        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'

无法将“System.Int32”类型的对象转换为“System.String”类型

What am I missing here?

我在这里缺少什么?

回答by Joey

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

您的列没有 type string。显然是int。所以使用:

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 andthe 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));
    }
    
  • 只选择你需要的。这主要是出于性能原因以及您必须明确说明列名的原因,因此如果您不兼容地更改架构,至少会得到一个合理的错误。
  • 使用名称访问字段,例如

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

    这样的事情也可以通过扩展方法很好的解决:

    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 GetStringlooks more or less like this:

而且GetString看起来或多或少是这样的:

public string GetString(int index)
{
    return (string) GetValue(index);
}

回答by Koen

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

您的列似乎没有 int 类型。为了避免这种情况,您可以使用列名而不是索引。

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

回答by Kamal

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..

我将 sqlcommand 更改为单个值,并将 dr.getstring() 的列号更改为 0.. 它有效。谢谢你们的帮助..我期待更多,因为我的项目只完成了一半..