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.