C# 从 SqlDataReader 填充数组(或数组列表)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1370543/
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-06 15:46:42  来源:igfitidea点击:

Fill an array (or arraylist) from SqlDataReader

c#ado.net

提问by ristonj

Is there a way to fill an array via a SqlDataReader (or any other C# ADO.NET object) without looping through all the items? I have a query that is returning a single column, and I want to put that into a string array (or ArrayList, or List, etc).

有没有办法通过 SqlDataReader(或任何其他 C# ADO.NET 对象)填充数组而不循环遍历所有项目?我有一个返回单列的查询,我想将其放入字符串数组(或 ArrayList 或 List 等)中。

采纳答案by Pavel Minaev

It is possible. In .NET 2.0+, SqlDataReaderinherits from DbDataReader, which implements IEnumerable(non-generic one). This means that you can use LINQ:

有可能的。在 .NET 2.0+ 中,SqlDataReader继承自DbDataReader,它实现了IEnumerable(非通用的)。这意味着您可以使用 LINQ:

List<string> list = (from IDataRecord r in dataReader
                     select (string)r["FieldName"]
                    ).ToList();

That said, the loop is still there, it's just hidden in Enumerable.Select, rather than being explicit in your code.

也就是说,循环仍然存在,它只是隐藏在 中Enumerable.Select,而不是在您的代码中显式显示。

回答by Andrew Hare

Since any IDataReaderimplementation (SqlDataReaderincluded) will be a forward-only reader by definition, no there is no way to do this without looping. Even if there were a framework library method to do this it would have to loop through the reader, just like you would.

由于根据定义,任何IDataReader实现(SqlDataReader包括)都将是只进阅读器,因此没有循环就无法做到这一点。即使有一个框架库方法可以做到这一点,它也必须像你一样循环遍历阅读器。

回答by Russ Cam

No, since SqlDataReaderis a forward-only read-only stream of rows from a SQL Server database, the stream of rows will be looped through whether explicitly in your code or hidden in a framework implementation (such as DataTable's Loadmethod).

不,由于SqlDataReader是来自 SQL Server 数据库的前向只读行流,因此无论是在代码中显式显示还是在框架实现中隐藏(例如 DataTable 的Load方法),行流都将循环通过。

It sounds like using a generic list and then returning the list as an array would be a good option. For example,

听起来像使用通用列表然后将列表作为数组返回将是一个不错的选择。例如,

List<int> list = new List<int>();

using (SqlDataReader reader = cmd.ExecuteReader())
{
    while (reader.Read())
    {
         list.Add(reader.GetInt32(0));
    }    
}
return list.ToArray();

In response to your comment, calling ToArray() may be overhead, it depends. Do you need an array of objects to work with or would a generic collection (such as List<T>or ReadOnlyCollection<T>) be more useful?

为了回应您的评论,调用 ToArray() 可能是开销,这取决于。您是否需要使用一组对象,或者通用集合(例如List<T>ReadOnlyCollection<T>)是否更有用?

回答by Chris Brandsma

You have to loop, but there are projects that can make it simpler. Also, try not to use ArrayList, use List instead.

你必须循环,但有些项目可以让它更简单。另外,尽量不要使用 ArrayList,而是使用 List。

You can checkout FluentAdo for one: http://fluentado.codeplex.com

您可以查看 FluentAdo 之一:http://fluentado.codeplex.com

    public IList<UserAccount> List()
    {
        var list = new FluentCommand<UserAccount>("SELECT ID, UserName, Password FROM UserAccount")
            .SetMap(reader => new UserAccount
            {
                ID = reader.GetInt("ID"),
                Password = reader.GetString("Password"),
                UserName = reader.GetString("UserName"),
            })
            .AsList();

        return list;
    }

回答by Rob Allen

If you read your SqlDataAdapter into a DataTable:

如果您将 SqlDataAdapter 读入数据表:

DataTable dt as DataTable; 
dt.fill(data);

Then you can use some of the toys in System.Data.DataSetExtensionsas referenced in Joel Muller's answer to this question.

然后,您可以使用System.Data.DataSetExtensionsJoel Muller 对这个问题的回答中提到的一些玩具

In uses a bit of Linq, so you will net .Net 3.5 or higher.

In 使用了一点 Linq,因此您将使用 .Net 3.5 或更高版本。

回答by JNF

Apparently, ever since .NET 1.1 SqlDataReaderhad the following method:

显然,从 .NET 1.1 开始SqlDataReader就有以下方法

int size;
object[] data = new object[]{};
size = reader.GetValues(data);

This populates datawith the values of the current reader row, assigning into size the number of objects that were put into the array.

这将填充data当前读取器行的值,将放入数组的对象数量分配给 size。

回答by RickIsWright

The orignial OP asked for Array, ArrayList or List. You can return Array as well. Just call the .ToArray() method and assign it to a previously declared array. Arrays are very fast when it comes to enumerating each element. Much faster than a List if the list has more than 1000 elements. You can return to Array, List, or Dictionary.

原始 OP 要求 Array、ArrayList 或 List。您也可以返回 Array。只需调用 .ToArray() 方法并将其分配给先前声明的数组。数组在枚举每个元素时非常快。如果列表有超过 1000 个元素,则比列表快得多。您可以返回到数组、列表或字典。

ids_array = (from IDataRecord r in idReader 
select (string)r["ID"]).ToArray<string>();  

Additionally, if you are using a lookup of keys for example, you might consider creating a HashSet object with has excellent lookup performance if you are simply checking one list against another to determine if an elements key exists in the HashSet object. example:

此外,如果您正在使用键的查找,例如,如果您只是简单地检查一个列表和另一个列表以确定元素键是否存在于 HashSet 对象中,您可能会考虑创建一个具有出色查找性能的 HashSet 对象。例子:

 HashSet<string> hs = new HashSet<string>( 
(from IDataRecord r in idReader select (string)r["ID"]).AsEnumerable<string>() );