将数据行返回到List<string>中,使用SqlDataReader。

4
我试图创建一个通用的SqlDataReader,将拥有33列的表格转化成一个列表。我希望每个列表项包含每行的所有33列值。
然而,我的代码将每个值分配给单独的列表项。所以,我有33,000个列表项,而不是1000个数据行。
我更喜欢使用列表而不是datatable,因为我需要比较的列表要简单得多。
如何使1000个列表项每个都有33个值?
   public static List<string> loadSQL(String query, String connectString)
    {
        List<string> dataList = new List<string>();

        using (SqlConnection connection = new SqlConnection(connectString))
        {
            using (SqlCommand command = new SqlCommand(query, connection))

            {
                connection.Open();

                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {

                        for (int i = 0; i < reader.FieldCount; i ++) 
                            { 
                                dataList.Add(Convert.ToString(reader.GetValue(i)));
                            }
                    }
                }
            }
        return dataList;

        }
    }

... 更新 ...

已更正为以下内容。它可以正确返回列表项。但是,我的列表包含33000个每个包含33个项目的项。我该如何控制循环以在1000行后停止?

        using (SqlConnection connection = new SqlConnection(connectString))
        {
            using (SqlCommand command = new SqlCommand(query, connection))

            {
                connection.Open();

                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {

                       List<string> tempRow = new List<string>();
                        for (int i = 0; i < reader.FieldCount; i ++) 
                            { 
                                tempRow.Add(Convert.ToString(reader.GetValue(i)));
                            }
                        dataList.Add(tempRow);

                    }
                }
            }
        }

顺便说一下,在你释放connection之前,你返回了dataList - choz
3个回答

5
您最好的选择是使用 DataTable 来完成此任务,但您不想使用它。因此,下一个选择是根据查询输出创建一个基于类的对象,然后使用 List<objectOftheClass>。但在您的情况下,输入查询将一直变化,因此通用类将没有意义,因为您试图使其更加通用。因此,您可以采用 List<List<string>>List<List<object>> 这个选项来进行操作。根据这个选项,方法签名将如下所示:
public static List<object[]> loadSQL(string query, string connectString)
{
    List<object[]> dataList = new List<object[]>();

    using (SqlConnection connection = new SqlConnection(connectString))
    {
        using (SqlCommand command = new SqlCommand(query, connection))
        {
            connection.Open();

            using (SqlDataReader reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    object[] tempRow = new object[reader.FieldCount];
                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        tempRow[i] = reader[i];
                    }
                    dataList.Add(tempRow);
                }
            }
        }
    }
    return dataList;
}

为什么使用 List<object> 而不是 `List`?
读者会将列数据作为表中相同类型的列提供。如果它是对象,则无需每次进行转换。
** 注意:** 在方法签名的参数中将String更改为string。您可以在此处找到原因:(链接)

与下面的另一个答案一样,使用次要列表并不是最好的答案,因为FieldCount是固定的,所以您可以使用数组。无论是List<object[]>还是List<string[]>,取决于您想如何存储结果。 - Gary Holland
感谢您的反馈。它可以正确返回列表项。然而,我的列表包含33,000个每个包含33个项目的项目。我该如何控制循环,使其在1000行后停止? - Richard
@Richard:我有点困惑,希望当前的代码会给你1000个列表项,每个列表项包含33个子项,对吗?那么为什么你需要在1000行后停止呢? - sujith karivelil
@un-lucky 我的数据库只有1000行。我想每行有一个列表项,然后33个子项代表列。 - Richard
@GaryHolland:是的,你说得对。我已经更新了答案。现在请告诉我,这个踩有什么意义吗? - sujith karivelil
这很好。我可以将数据放入List<object[]>中。你知道如何获取列名吗? - KMR

1
您可以这样使用 List<List<string>>
public static List<List<string>> loadSQL(String query, String connectString)
    {
        List<List<string>> dataList = new List<List<string>>();

        using (SqlConnection connection = new SqlConnection(connectString))
        {
            using (SqlCommand command = new SqlCommand(query, connection))

            {
                connection.Open();

                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var l = new List<string>();
                        for (int i = 0; i < reader.FieldCount; i ++) 
                            { 
                                l.Add(Convert.ToString(reader.GetValue(i)));
                            }
                        dataList.Add(l);
                    }
                }
            }
        return dataList;

        }
    }

1
我建议使用List<string[]>,因为FieldCount是固定的,所以没有必要再使用第二个动态数组增加额外开销。 - Gary Holland
抱歉,我应该表达得更清楚。在未来的实现中,FieldCount将需要是可变的。 - Richard

0

你可以在列表中使用数组来实现你想要做的事情。这里是一个使用你的代码的快速示例:

public static List<string[]> loadSQL(String query, String connectString)
{
List<string[]> dataList = new List<string[]>();

using (SqlConnection connection = new SqlConnection(connectString))
{
    using (SqlCommand command = new SqlCommand(query, connection))

    {
        connection.Open();

        using (SqlDataReader reader = command.ExecuteReader())
        {
            int rowcounter = 0;

            while (reader.Read())
            {
                string[] value = new string[reader.FieldCount];

                for (int i = 0; i < reader.FieldCount; i ++) 
                    { 
                        value[i] = Convert.ToString(reader.GetValue(i));
                    }

                dataList.Add(value);
                rowcounter++;
            }
        }
    }
return dataList;

}

或者,如果你想使用列表,你需要将数值嵌入到单个字符串中,使用逗号分隔符或类似的方式。


由于存在许多语法错误,您可以将其作为新问题发布。例如 object[i]=... - sujith karivelil
你测试过了吗?你的回答还有语法错误。与其对其他答案进行贬低,不如先修正自己的答案。 - sujith karivelil
是的。我对你的回答很感兴趣,但我收到了错误信息:“在dataList.Add(value);上,名称'value'在当前上下文中不存在。” 你有什么想法吗? - Richard
抱歉,我现在在手机上无法测试。我认为错误是由于使用了 object[] 而不是 string[] 导致的。请现在尝试,我回到电脑后会进行适当的修复。 - Gary Holland
@un-lucky,我给你点了踩是因为在评论中你声明了一个列表,而数组才是更好的答案。 - Gary Holland

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接