read executereader ejemplos data c# ado.net

c# - executereader - Rellene una matriz(o arrailista) desde SqlDataReader



sqldatareader read (7)

¿Hay una manera de llenar una matriz a través de un SqlDataReader (o cualquier otro objeto C # ADO.NET) sin hacer un bucle a través de todos los elementos? Tengo una consulta que está devolviendo una sola columna y quiero colocarla en una matriz de cadenas (o ArrayList, o Lista, etc.).


Aparentemente, desde entonces .NET 1.1 SqlDataReader tenía el siguiente método :

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

Esto llena los data con los valores de la fila del lector actual, asignando en tamaño la cantidad de objetos que se colocaron en la matriz.


Dado que cualquier implementación de IDataReader ( SqlDataReader incluida) será un lector de solo avance, por definición, no hay forma de hacer esto sin hacer un bucle. Incluso si hubiera un método de biblioteca de marco para hacer esto, tendría que recorrer el lector, como usted lo haría.


El PO inicial solicitó Array, ArrayList o List. Puedes devolver Array también. Simplemente llame al método .ToArray () y asígnele una matriz previamente declarada. Las matrices son muy rápidas cuando se trata de enumerar cada elemento. Mucho más rápido que una lista si la lista tiene más de 1000 elementos. Puede volver a Array, Lista o Diccionario.

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

Además, si está utilizando una búsqueda de claves, por ejemplo, puede considerar crear un objeto HashSet con un excelente rendimiento de búsqueda si simplemente está comparando una lista con otra para determinar si existe una clave de elementos en el objeto HashSet. ejemplo:

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


No, dado que SqlDataReader es un flujo de filas de solo lectura de una base de datos de SQL Server, el flujo de filas se realizará en bucle ya sea explícitamente en su código u oculto en una implementación de marco (como el método de Load de DataTable).

Parece que usar una lista genérica y luego devolver la lista como una matriz sería una buena opción. Por ejemplo,

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

En respuesta a su comentario, llamar a ToArray () puede ser una sobrecarga, depende. ¿Necesita una matriz de objetos con los que trabajar o sería más útil una colección genérica (como List<T> o ReadOnlyCollection<T> )?


Si lees tu SqlDataAdapter en un DataTable:

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

Luego puedes usar algunos de los juguetes en System.Data.DataSetExtensions como se hace referencia en la respuesta de Joel Muller a esta question.

En usa un poco de Linq, así que obtendrás .Net 3.5 o superior.


Tienes que hacer un bucle, pero hay proyectos que pueden simplificarlo. Además, trate de no usar ArrayList, use List en su lugar.

Puede pagar FluentAdo por uno: 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; }


Es posible. En .NET 2.0+, SqlDataReader hereda de DbDataReader , que implementa IEnumerable (uno no genérico). Esto significa que puedes usar LINQ:

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

Dicho esto, el bucle todavía está allí, simplemente está oculto en Enumerable.Select , en lugar de ser explícito en su código.