from - DataReader o DataSet al extraer varios conjuntos de registros en ASP.NET
using sqldatareader vb net (10)
Tengo una página ASP.NET que tiene muchos controles que deben completarse (por ejemplo, listas desplegables).
Me gustaría hacer un solo viaje a la base de datos y traer múltiples conjuntos de registros en lugar de hacer un viaje de ida y vuelta para cada control.
Podría traer varias tablas en un DataSet, o podría recuperar un DataReader y usar ''.NextResult'' para poner cada conjunto de resultados en una clase de negocios personalizada.
¿Es probable que vea una ventaja de rendimiento lo suficientemente grande usando el enfoque de DataReader, o debería usar el enfoque DataSet?
Cualquier ejemplo de cómo se maneja generalmente esto sería apreciado.
Asigne el DataReader a objetos intermedios y luego vincule sus controles con esos objetos. Puede estar bien utilizar los DataSets en ciertas circunstancias, pero son pocos y distantes entre sí cuando tiene razones poderosas para "solo obtener datos". Hagas lo que hagas, no pases un DataReader a tus controles para desvincularlo (no es que hayas dicho que lo estás considerando).
Mi preferencia personal sería usar un ORM, pero si va a transferir manualmente su acceso a los datos, creo que debería preferir mapear DataReaders a objetos antes que usar DataSets. Usar el .NextResult como una manera de limitarse de golpear la base de datos varias veces es una espada de doble filo, así que elija sabiamente. Te encontrarás repitiendo a ti mismo si tratas de crear procs que siempre toman exactamente lo que necesitas usando solo una llamada a la base de datos. Si su aplicación tiene solo unas pocas páginas, probablemente esté bien, pero las cosas se pueden descontrolar rápidamente. Personalmente prefiero tener un proc por tipo de objeto y luego presionar la base de datos varias veces (una para cada tipo de objeto) para maximizar la capacidad de mantenimiento. Aquí es donde brilla un ORM porque uno bueno generará Sql que le dará exactamente lo que quiere con una llamada en la mayoría de los casos.
Eche un vistazo a los TableAdapters que están disponibles con .NET 2.0 y versiones posteriores. Lo que hacen es darle la fortaleza de una DataTable fuertemente tipada y le permiten mapear un método de relleno que usará un DataReader para cargarlo. Su método de llenado puede ser procedimientos almacenados existentes, su propio AdHoc SQL o incluso dejar que el asistente genere AdHod o el Procedimiento almacenado para usted.
Puede encontrarlo iniciando un nuevo objeto XSD DataSet dentro de su proyecto. Para las tablas que se utilizan para algo más que la búsqueda, también puede asignar los métodos de inserción / actualización / eliminación al TableAdapter.
En casi todas las situaciones, DataReader
s es la mejor solución para leer desde una base de datos. DataReader
s son más rápidos y requieren menos memoria que DataTable
o DataSet
.
Además, DataSet
s a menudo puede conducir a situaciones en las que el modelo OO está roto . No está muy orientado a objetos pasar datos / esquemas relacionales en lugar de objetos que saben cómo manipular esos datos.
Por lo tanto, para razones de extensibilidad, escalabilidad, modularidad y rendimiento, siempre use DataReader
si se considera un Real Programmer ™;)
Revise los enlaces para ver los hechos y la discusión sobre los dos en práctica y teoría.
He recurrido a un método que utiliza DataReaders para todas las llamadas, he notado un marcado empeoramiento en el rendimiento, especialmente en los casos en que estoy cargando listas desplegables, y otros elementos simples como ese.
Personalmente con varios menús desplegables, normalmente voy a pulir fragmentos de datos individuales para obtenerlo, en lugar de decir un procedimiento almacenado que devuelve 5 conjuntos de resultados.
Si no está interesado en actualizar o eliminar los registros que ha extraído de la base de datos, le sugiero que use DataReader. Básicamente, DataSet utiliza internamente múltiples Datareaders, por lo que DataReader debería ofrecerle una buena ventaja de rendimiento.
Si su proc almacenado devuelve varios conjuntos, use el DataReader.NextResult para avanzar al siguiente fragmento de datos. De esta forma, puede obtener todos sus datos, cargarlos en sus objetos y cerrar el lector lo antes posible. Este será el método más rápido para obtener sus datos.
Siempre coloque sus datos en las clases definidas para el uso específico. No pase los DataSets ni los DataReaders.
- Si tiene más de 1000 registros para traer de su Base de Datos.
- Si no está muy interesado con el almacenamiento personalizado y la paginación personalizada " For GridView "
- Si su servidor tiene un estrés de memoria.
- Si no hay ningún problema para conectarse a su base de datos cada vez que esa página llame.
Entonces creo que es mejor usar DataReader.
más
- Si tiene menos de 1000 registros para traer de su Base de Datos.
- Si está interesado en almacenar y paginar " For GridView "
- Si su servidor no tiene un estrés de memoria.
- Si desea conectarse a su DataBase solo una vez y obtener los beneficios de Caching .
Entonces creo que lo mejor es usar DataSet.
Supongo que estoy en lo correcto.
Independientemente de si está buscando un solo conjunto de resultados o conjuntos de resultados múltiples, parece que el consenso es utilizar un DataReader en lugar de un DataSet.
Con respecto a si alguna vez debería molestarse con múltiples conjuntos de resultados, la sabiduría es que no debería, pero puedo concebir una clase razonable de excepciones a esa regla: (estrechamente) conjuntos de resultados relacionados. Ciertamente no desea agregar una consulta para devolver el mismo conjunto de opciones para una lista desplegable que se repite en cientos o incluso en decenas de páginas en su aplicación, pero varios conjuntos de uso restringido pueden combinarse con sensatez. Como ejemplo, actualmente estoy creando una página para mostrar varios conjuntos de ''discrepancias'' para un lote de datos de ETL. Es probable que ninguna de esas consultas se use en otro lugar, por lo que sería conveniente encapsularlas como una sola operación de ''obtener discrepancias''. Por otro lado, el mejor rendimiento al hacerlo puede ser insignificante si se compara con la arquitectura natural de un solo resultado de un solo resultado de su ORM o código de acceso a datos rodado a mano.
Al ver que todavía no se ha marcado ninguna respuesta, aunque ya hay buenas respuestas, pensé que también agregaría dos bits.
Usaría DataReaders, ya que son un poco más rápidos (si el rendimiento es lo tuyo o si necesitas todo lo que puedas obtener). La mayoría de los proyectos en los que he trabajado tienen millones de registros en cada una de las tablas y el rendimiento es una preocupación.
Algunas personas han dicho que no es una buena idea enviar DataReader en varias capas. Personalmente, no veo esto como un problema ya que un "DbDataReader" no está técnicamente vinculado (o no tiene que serlo) a una base de datos. Es decir, puede crear una instancia de un DbDataReader sin necesidad de una base de datos.
Por qué lo hago es por las siguientes razones: con frecuencia (en una aplicación web) está generando ya sea HTML, Xml o JSON o alguna otra transformación de sus datos. Entonces, ¿por qué pasar de un DaraReader a un objeto POCO solo para transformarlo de nuevo a XML o JSON y enviarlo por cable? Este tipo de proceso normalmente requiere 3 transformaciones y una carga de inicio de instanciaciones de objetos solo para descartarlas casi instantáneamente.
En algunas situaciones, eso está bien o no se puede evitar. Mi capa de datos normalmente muestra dos métodos para cada procedimiento almacenado que tengo en el sistema. Uno devuelve un DbDataReader y el otro devuelve un DataSet / DataTable. Los métodos que devuelven un DataSet / DataTable llaman al método que devuelve un DbDataReader y luego utiliza el método "Load" de DataTable o un adaptador para llenar el conjunto de datos. A veces necesita DataSets porque probablemente tenga que readaptar los datos de alguna manera o necesita disparar otra consulta y, a menos que tenga MARS habilitado, no puede tener un DbDataReader abierto y disparar otra consulta.
Ahora hay algunos problemas con el uso de DbDataReader o DataSet / DataTable, que suelen ser claridad de código, comprobación de tiempo de compilación, etc. Puede usar clases de contenedor para su lector de datos y, de hecho, puede usar sus DataReaders como IEnumerable. Capacidad realmente genial. ¡Así que no solo obtienes un tipeo fuerte y legibilidad de código sino que también obtienes IEnumerable!
Entonces una clase podría verse así.
public sealed class BlogItemDrw : BaseDbDataReaderWrapper
{
public Int64 ItemId { get { return (Int64)DbDataReader[0]; } }
public Int64 MemberId { get { return (Int64)DbDataReader[1]; } }
public String ItemTitle { get { return (String)DbDataReader[2]; } }
public String ItemDesc { get { if (DbDataReader[3] != DBNull.Value) return (String)DbDataReader[3]; else return default(String); } }
public DateTime ItemPubdate { get { return (DateTime)DbDataReader[4]; } }
public Int32 ItemCommentCnt { get { return (Int32)DbDataReader[5]; } }
public Boolean ItemAllowComment { get { return (Boolean)DbDataReader[6]; } }
public BlogItemDrw()
:base()
{
}
public BlogItemDrw(DbDataReader dbDataReader)
:base(dbDataReader)
{
}
}
Tengo una publicación de blog (enlace arriba) que entra en muchos más detalles y haré un generador de código fuente para estos y otros códigos de capa de DataAccess.
Puede usar la misma técnica para DataTables (el generador de códigos produce el código) para que pueda tratarlos como DataTable fuertemente tipificado sin la sobrecarga de lo que VS.NET proporciona de manera predeterminada.
Tenga en cuenta que solo hay una instancia de la clase contenedora. Entonces no estás creando cientos de instancias de una clase solo para tirarlas.