坚持使用SqlDataReader.GetValues方法

Rob*_*Rob 2 c# sql asp.net datareader

我正在调用一个SQL存储过程,它返回一个用户及其老板的小表.我想要做的是将此信息与我的应用程序的不同部分中的变量进行比较,以启用/取消编辑GridView行.为了实现这一点,似乎该GetValues方法将返回我需要的东西,即存储过程返回的整个数据集.我的想法是,一旦我在我的应用程序中拥有该数据,我就可以将该数据集加载到一个数组中,并循环遍历它以完成我需要做的事情.

问题是这个.在我下面的代码中,我收到错误

无法将类型'int'隐式转换为'object'

当我查看有关此方法的文档时,返回值为int.

我的问题是,既然存储过程包含字符串数据(用户名和老板名),为什么GetValuesmehtod会返回int?我的实际数据如何表示为数字?如何将数据转换为基于字符串的数组?

我一直在寻找互联网上的许多例子和信息,这似乎是新人们常见的问题.我只是不理解或得到它,我没有取得任何进展.任何帮助是极大的赞赏!

    public Object[] GetDeptAppData()
    {
        Object[] myObject;
        string sp_deptapp, sp_status, sp_supervisor;

        //execute stored procedure to get data from database
        SqlConnection sqlConnection = new SqlConnection("Data Source=MyServer;Initial Catalog=MyCatalog;Persist Security Info=True;User ID=MyUser;Password=MyPassword");
        SqlCommand cmd = new SqlCommand();
        SqlDataReader reader;

        cmd.CommandText = "SP_Admin_DeptApp_Load";
        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Connection = sqlConnection;
        sqlConnection.Open();
        reader = cmd.ExecuteReader();

        if (reader.HasRows == true)
        {
            //sp_deptapp = reader.GetValue(0).ToString();
            //sp_status = reader.GetValue(1).ToString();
            //sp_supervisor = reader.GetValue(2).ToString();

            myObject = reader.GetValues(myObject);
        }
        else
        {
            //nothing in reader, throw exception
        }
        sqlConnection.Close();

        return myObject;
    }
Run Code Online (Sandbox Code Playgroud)

Mar*_*kus 10

您遇到的错误位于以下行:

myObject = reader.GetValues(myObject);
Run Code Online (Sandbox Code Playgroud)

myObject是一个对象数组,该GetValues方法返回一个整数,该整数包含放置在数组中的计数.因此,为了解决您的错误,您可以将行更改为以下内容:

var count = reader.GetValues(myObject);
Run Code Online (Sandbox Code Playgroud)

此外,在您的代码中,您只检索一行数据.这当然是好的,如果你只想要一排.当期望多行时,您通常会循环遍历这样的行:

while (reader.Read())
{
    // Read row and add row to list
}
Run Code Online (Sandbox Code Playgroud)

有关如何使用SqlDataReader的示例,请参阅此链接.


样品

如果要检索多行并存储数据,我建议添加一个类来存储行的数据(您可能希望验证数据类型以使它们与SP返回的类型匹配):

public class Data
{
    public string DeptApp { get; set; }
    public string Status { get; set; } // this might be another data type
    public string Supervisor { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后检索行,如下所示:

public Data[] GetDeptAppData()
{
    //execute stored procedure to get data from database
    using (SqlConnection sqlConnection = new SqlConnection("Data Source=MyServer;Initial Catalog=MyCatalog;Persist Security Info=True;User ID=MyUser;Password=MyPassword"))
    {
        SqlCommand cmd = new SqlCommand();
        cmd.CommandText = "SP_Admin_DeptApp_Load";
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Connection = sqlConnection;
        sqlConnection.Open();
        using (var reader = cmd.ExecuteReader())
        {
            if (!reader.HasRows)
            {
                // throw exception
            }
            var lst = new List<Data>();
            while (reader.Read())
            {
                var row = new Data();
                row.DeptApp = reader.GetString(0);
                row.Status = reader.GetString(1);
                row.Supervisor = reader.GetString(2);
                lst.Add(row);
            }
            return lst.ToArray();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


And*_*own 5

GetValues返回一个int数组中对象实例的数量”。,因此您不能将其分配给myObject. 这很神秘。它实际上意味着(我相信)为当前行返回的列值的数量。

你需要:

int numColumnsRetrieved = reader.GetValues(myObject);
Run Code Online (Sandbox Code Playgroud)

或类似的东西。

然后,您的数据将出现在内部myObject,但仅适用于当前行,根据文档“使用当前行的列值填充对象数组”。所以,你还是需要迭代,比如:

var myObjectList = new List<object[]>(); // ... shudder ...
while (reader.Read())
{
    var myObject[] = new object[reader.FieldCount];
    int instances = reader.GetValues(myObject);
    myObjectList.Add(myObject);
}
Run Code Online (Sandbox Code Playgroud)

您可能会发现使用更具体的方法很有用,例如GetString

var usersAndBosses = new List<Tuple<string, string>>();
while (reader.Read())
{
    string username = reader.GetString(0); // column index 0
    string bossname = reader.GetString(1); // column index 1
    usersAndBosses.Add(Tuple.Create(username, bossname));
}
Run Code Online (Sandbox Code Playgroud)

编辑

如果您想对 的返回值进行虚假使用GetValues,您可以将字符串表展平为字符串列表:

var myStringList = new List<string>();
while (reader.Read())
{
    var myObject[] = new object[100];
    int colCount = reader.GetValues(myObject);
    for (int i = 0; i < colCount; i++)
    {
        myStringList.Add((string)myObject[i]);
    }
}
Run Code Online (Sandbox Code Playgroud)