Академический Документы
Профессиональный Документы
Культура Документы
ADO.NET
Novedades de ADO.NET
Información general sobre ADO.NET
Arquitectura de ADO.NET
Directrices y opciones de tecnología de ADO.NET
LINQ y ADO.NET
Proveedores de datos .NET Framework
Objetos DataSet de ADO.NET
Ejecución en paralelo en ADO.NET
Ejemplos de código de ADO.NET
Proteger aplicaciones de ADO.NET
Información general sobre seguridad
Acceso seguro a datos
Aplicaciones cliente seguras
Seguridad de acceso del código y ADO.NET
Privacidad y seguridad de datos
Asignaciones de tipos de datos en ADO.NET
Asignaciones de tipos de datos de SQL Server
Asignaciones de tipos de datos de OLE DB
Asignaciones de tipos de datos de ODBC
Asignaciones de tipos de datos de Oracle
Números de punto flotante
Recuperar y modificar datos en ADO.NET
Conectarse a un origen de datos
Establecer la conexión
Eventos de Connection
Cadenas de conexión
Generadores de cadenas de conexión
Cadenas de conexión y archivos de configuración
Sintaxis de cadenas de conexión
Proteger la información de conexión
Agrupación de conexiones
Agrupación de conexiones de SQL Server (ADO.NET)
Agrupación de conexiones de OLE DB, ODBC y Oracle
Comandos y parámetros
Ejecutar un comando
Configurar parámetros y tipos de datos de parámetros
Generar comandos con objetos CommandBuilder
Obtener un valor único de una base de datos
Usar comandos para modificar datos
Actualizar datos de un origen de datos
Realizar operaciones de catálogo
Objetos DataAdapter y DataReader
Recuperar datos utilizando un objeto DataReader
Rellenar un conjunto de datos desde un objeto DataAdapter
Parámetros de DataAdapter
Agregar restricciones existentes a un conjunto de datos
Correspondencias de DataTable y DataColumn en un objeto DataAdapter
Paginar un resultado de consulta
Actualizar orígenes de datos con objetos DataAdapter
Controlar eventos de DataAdapter
Realizar operaciones por lotes utilizando objetos DataAdapter
Transacciones y simultaneidad
Transacciones locales
Transacciones distribuidas
Integración de System.Transactions con SQL Server
Simultaneidad optimista
Recuperar valores autonuméricos y de identidad
Recuperar datos binarios
Modificar datos con procedimientos almacenados
Recuperar información del esquema de la base de datos
GetSchema y colecciones de esquema
GetSchema y colecciones de esquema
Restricciones de esquema
Colecciones de esquemas comunes
Colecciones de esquemas de SQL Server
Colecciones de esquemas de Oracle
Colecciones de esquemas de ODBC
Colecciones de esquemas de OLE DB
Objetos DbProviderFactory
Información general sobre el modelo de fábrica
Obtener un objeto DbProviderFactory
DbConnection, DbCommand y DbException
Modificar datos con un objeto DbDataAdapter
Traza de datos en ADO.NET
Contadores de rendimiento
Programación asincrónica
Compatibilidad de transmisión de datos de SqlClient
LINQ to DataSet
Introducción
Información general de LINQ to DataSet
Cargar datos en un conjunto de datos
Descargar bases de datos de ejemplo
Procedimiento para crear un proyecto de LINQ to DataSet en Visual Studio
Guía de programación
Consultas en LINQ to DataSet
Consulta de conjuntos de datos
Consultas de tabla única
Consultas entre tablas
Consultar objetos DataSet con tipo
Comparación de objetos DataRow
Creación de un objeto DataTable a partir de una consulta
Procedimiento para implementar CopyToDataTable<T> cuando el tipo genérico T
no es un objeto DataRow
Métodos genéricos Field y SetField
Enlace de datos y LINQ to DataSet
Creación de un objeto DataView
Filtrado con DataView
Ordenación con DataView
Consultar la colección de DataRowView en un objeto DataView
Rendimiento de DataView
Procedimiento para enlazar un objeto DataView a un control DataGridView de
formularios Windows Forms
Depurar consultas de LINQ to DataSet
Seguridad
Ejemplos de LINQ to DataSet
Ejemplos de expresiones de consultas
Proyección
Restricción
Particionamiento
Ordenación
Operadores de elementos
Operadores de agregado
Operadores de combinación
Ejemplos de consultas basadas en métodos
Proyección
Particionamiento
Ordenación
Operadores de conjuntos
Operadores de conversión
Operadores de elementos
Operadores de agregado
Join
Ejemplos de operadores específicos de conjuntos de datos
Entity Data Model
Conceptos clave de Entity Data Model
Entity Data Model: Espacios de nombres
Entity Data Model: tipos de datos primitivos
Entity Data Model: Herencia
extremo de asociación
multiplicidad de extremo de asociación
conjunto de asociaciones
extremo del conjunto de asociaciones
tipo de asociación
tipo complejo
contenedor de entidades
clave de entidad
conjunto de entidades
tipo de entidad
facet
propiedad de clave externa
función declarada por el modelo
función definida por el modelo
propiedad de navegación
propiedad
restricción de integridad referencial
Oracle y ADO.NET
Requisitos del sistema
Objetos BFILE de Oracle
Objetos LOB de Oracle
Parámetros REF CURSOR de Oracle
Ejemplos de REF CURSOR
Parámetros REF CURSOR en un objeto OracleDataReader
Recuperar datos desde varios parámetros REF CURSOR utilizando un objeto
OracleDataReader
Rellenar un conjunto de datos utilizando uno o varios parámetros REF CURSOR
Tipos de Oracle
Secuencias de Oracle
Asignaciones de tipos de datos de Oracle
Transacciones distribuidas de Oracle
ADO.NET Entity Framework
SQL Server y ADO.NET
Objetos DataSet, DataTable y DataView
ADO.NET
10/02/2020 • 3 minutes to read • Edit Online
ADO.NET es un conjunto de clases que exponen servicios de acceso a datos para programadores de .NET
Framework. ADO.NET ofrece abundancia de componentes para la creación de aplicaciones de uso compartido de
datos distribuidas. Constituye una parte integral de .NET Framework y proporciona acceso a datos relacionales,
XML y de aplicaciones. ADO.NET satisface diversas necesidades de desarrollo, como la creación de clientes de base
de datos front-end y objetos empresariales de nivel medio que utilizan aplicaciones, herramientas, lenguajes o
exploradores de Internet.
En esta sección
Novedades de ADO.NET
Presenta características nuevas en ADO.NET.
Información general sobre ADO.NET
Proporciona una introducción al diseño y a los componentes de ADO.NET.
Entity Framework
Describe cómo crear aplicaciones con Entity Framework.
Proteger aplicaciones de ADO.NET
Describe algunas recomendaciones de codificación segura para utilizar ADO.NET.
Asignaciones de tipos de datos en ADO.NET
Describe las asignaciones de tipos de datos entre los tipos de datos de .NET Framework y los proveedores de datos
.NET Framework.
Objetos DataSet, DataTable y DataView
Describe cómo crear y usar DataSets , DataSets con establecimiento de tipos, DataTables y DataViews .
LINQ to DataSet
Proporciona información sobre LINQ to DataSet, incluidos ejemplos de programación.
Recuperar y modificar datos en ADO.NET
Describe cómo conectarse a un origen de datos y cómo recuperar y modificar datos mediante Commands ,
DataReaders y DataAdapters .
Secciones relacionadas
Language Integrated Query (LINQ) (C#)
Proporciona vínculos a temas y ejemplos de LINQ C#mediante.
Language Integrated Query (LINQ) (Visual Basic)
Proporciona vínculos a temas y ejemplos de LINQ mediante Visual Basic.
Servicios de datos de WCF 4.5
Describe cómo usar WCF Data Services para implementar servicios de datos en Internet o en una intranet que
implementa el Open Data Protocol (OData).
Guía de desarrollo para .NET Framework
Proporciona vínculos a información acerca de las tareas de desarrollo estándar en .NET Framework.
Ejemplos y tutoriales
Proporciona una lista de ejemplos y tutoriales de .NET.
Consulte también
Obtener acceso a los datos en Visual Studio
Información general sobre ADO.NET
Novedades de ADO.NET
05/02/2020 • 5 minutes to read • Edit Online
Vea también
ADO.NET
Información general sobre ADO.NET
SQL Server y ADO.NET
Novedades de WCF Data Services 5,0
Información general sobre ADO.NET
05/02/2020 • 5 minutes to read • Edit Online
ADO.NET proporciona acceso coherente a orígenes de datos como SQL Server y XML, así como a
orígenes de datos expuestos mediante OLE DB y ODBC. Las aplicaciones de consumidor que
comparten datos pueden utilizar ADO.NET para conectar a estos orígenes de datos y recuperar,
controlar y actualizar los datos contenidos.
ADO.NET separa el acceso a datos de la manipulación de datos y crea componentes discretos que se
pueden utilizar por separado o conjuntamente. ADO.NET incluye proveedores de datos .NET
Framework para conectarse a una base de datos, ejecutar comandos y recuperar resultados. Los
resultados se procesan directamente o se colocan en un objeto DataSet de ADO.NET con el fin de
exponerlos al usuario para un propósito específico, combinados con datos de varios orígenes, o de
pasarlos entre niveles. El objeto DataSet de ADO.NET también puede utilizarse independientemente de
un proveedor de datos .NET Framework para administrar datos que son locales de la aplicación o que
proceden de un origen XML.
Las clases de ADO.NET se encuentran en System.Data.dll y se integran con las clases de XML incluidas
en System.Xml.dll. Para ver el código de ejemplo que se conecta a una base de datos, recupera datos de
la misma y, a continuación, muestra esos datos en una ventana de la consola, consulte ejemplos de
código ADO.net.
ADO.NET proporciona funcionalidad a los desarrolladores que escriben código administrado similar a
la funcionalidad que los objetos ADO (ActiveX Data Objects) proporcionan a los desarrolladores de
modelo de objetos componentes (COM) nativo. Se recomienda utilizar ADO.NET, y no ADO, para
obtener acceso a datos de aplicaciones .NET.
ADO.NET proporciona el método más directo de acceso a datos de .NET Framework. Para obtener una
abstracción de nivel superior que permita que las aplicaciones funcionen con un modelo conceptual en
lugar del modelo de almacenamiento subyacente, vea el Entity Framework ADO.net.
Declaración de privacidad : los ensamblados System. Data. dll, System. Data. Design. dll, System.
Data. OracleClient. dll, System. Data. SqlXml. dll, System. Data. Linq. dll, System. Data. SqlServerCe. dll y
System. Data. DataSetExtensions. dll no distinguen entre los datos privados de un usuario y los datos
no privados. Estos ensamblados no recopilan, almacenan o transportan datos privados del usuario. No
obstante, las aplicaciones de terceros podrían recopilar, almacenar o transportar datos privados de
usuario valiéndose de dichos ensamblados.
Esta sección
Arquitectura de ADO.NET
Proporciona información general sobre la arquitectura y los componentes de ADO.NET.
Directrices y opciones de tecnología de ADO.NET
Describe los productos y tecnologías incluidos con la plataforma de datos de entidad.
LINQ y ADO.NET
Describe cómo se implementa Language-Integrated Query (LINQ) en ADO.NET y proporciona vínculos
a los temas pertinentes.
Proveedores de datos .NET Framework
Proporciona información general acerca del diseño del proveedor de datos .NET Framework y de los
proveedores de datos .NET Framework incluidos en ADO.NET.
Objetos DataSet de ADO.NET
Proporciona información general acerca del diseño y los componentes de DataSet .
Ejecución en paralelo en ADO.NET
Analiza las diferencias que existen entre las distintas versiones de ADO.NET y cómo afectan a la
ejecución en paralelo y a la compatibilidad entre aplicaciones.
Ejemplos de código de ADO.NET
Proporciona ejemplos de código que recuperan datos mediante proveedores de datos de ADO.NET.
Secciones relacionadas
Novedades de ADO.NET
Presenta características nuevas en ADO.NET.
Proteger aplicaciones de ADO.NET
Describe algunas recomendaciones de codificación segura para utilizar ADO.NET.
Asignaciones de tipos de datos en ADO.NET
Describe las asignaciones de tipos de datos entre los tipos de datos de .NET Framework y los
proveedores de datos .NET Framework.
Recuperar y modificar datos en ADO.NET
Describe cómo conectarse a un origen de datos, y cómo recuperar y modificar datos. Incluye
DataReaders y DataAdapters .
Vea también
ADO.NET
Obtener acceso a los datos en Visual Studio
Arquitectura de ADO.NET
05/02/2020 • 9 minutes to read • Edit Online
Componentes de ADO.NET
Los dos componentes principales de ADO.NET para tener acceso a los datos y manipularlos son los .NET
Framework proveedores de datos y el DataSet.
Proveedores de datos .NET Framework
Los proveedores de datos .NET Framework son componentes diseñados explícitamente para la manipulación de
datos y el acceso rápido a datos de solo lectura y solo avance. El objeto Connection proporciona conectividad a un
origen de datos. El objeto Command permite tener acceso a comandos de base de datos para devolver datos,
modificar datos, ejecutar procedimientos almacenados y enviar o recuperar información sobre parámetros.
DataReader proporciona un flujo de datos de alto rendimiento desde el origen de datos. Por último, el objeto
DataAdapter proporciona el puente entre el objeto DataSet y el origen de datos. DataAdapter utiliza objetos
Command para ejecutar comandos SQL en el origen de datos tanto para cargar DataSet con datos y reconciliar en
el origen de datos los cambios aplicados a los datos incluidos en el DataSet . Para obtener más información, vea
.NET Framework proveedores de datos y recuperar y modificar datos en ADO.net.
DataSet
DataSet de ADO.NET está expresamente diseñado para el acceso a datos independientemente del origen de datos.
Como resultado, se puede utilizar con múltiples y distintos orígenes de datos, con datos XML o para administrar
datos locales de la aplicación. DataSet contiene una colección de uno o más objetos DataTable formados por filas y
columnas de datos, así como información sobre claves principales, claves externas, restricciones y de relación
relacionada con los datos incluidos en los objetos DataTable . Para obtener más información, vea conjuntos de
datos , tablas de datos y vistasde datos.
En el diagrama siguiente se ilustra la relación entre un proveedor de datos de .NET Framework y un DataSet .
Arquitectura de ADO.NET
Elegir un DataReader o un DataSet
Cuando decida si la aplicación debe usar un DataReader (vea recuperación de datos mediante un DataReader) o un
DataSet (vea conjuntos de datos , DataTables y vistasde datos), tenga en cuenta el tipo de funcionalidad que
requiere la aplicación. Use un DataSet para hacer lo siguiente:
Almacene datos en la memoria caché de la aplicación para poder manipularlos. Si solamente necesita leer
los resultados de una consulta, el DataReader es la mejor elección.
Utilizar datos de forma remota entre un nivel y otro o desde un servicio Web XML.
Interactuar con datos dinámicamente, por ejemplo para enlazar con un control de Windows Forms o para
combinar y relacionar datos procedentes de varios orígenes.
Realizar procesamientos exhaustivos de datos sin necesidad de tener una conexión abierta con el origen de
datos, lo que libera la conexión para que la utilicen otros clientes.
Si no necesita la funcionalidad proporcionada por el DataSet , puede mejorar el rendimiento de su aplicación si
utiliza el DataReader para devolver sus datos de solo avance y de solo lectura. Aunque el DataAdapter usa el
DataReader para rellenar el contenido de un DataSet (vea rellenar un conjunto de resultados de un DataAdapter),
mediante el DataReader , puede mejorar el rendimiento porque ahorrará memoria que consumirá el DataSet y
evitará el procesamiento necesario para crear y rellenar el contenido de la DataSet .
LINQ to DataSet
LINQ to DataSet proporciona capacidades de consulta y comprobación de tipo en tiempo de compilación de los
datos almacenados en caché de un objeto DataSet. Permite escribir consultas en uno de los lenguajes de desarrollo
de .NET Framework, como C# o Visual Basic. Para más información, vea LINQ to DataSet.
LINQ to SQL
LINQ to SQL admite consultas en un modelo de objetos asignado a las estructuras de datos de una base de datos
relacional sin utilizar un modelo conceptual intermedio. Cada tabla se representa mediante una clase distinta,
acoplando de manera precisa el modelo de objetos al esquema de la base de datos relacional. LINQ to SQL
convierte las consultas de Language-Integrated Query del modelo de objetos a Transact-SQL y las envía a la base
de datos para su ejecución. Cuando la base de datos devuelve los resultados, LINQ to SQL los vuelve a traducir a
objetos. Para más información, vea LINQ to SQL.
XML y ADO.NET
ADO.NET aprovecha la eficacia de XML para proporcionar acceso sin conexión a los datos. ADO.NET se diseñó a
mano con las clases XML del .NET Framework; ambos son componentes de una única arquitectura.
ADO.NET y las clases XML del .NET Framework convergen en el objeto DataSet . DataSet se puede rellenar con
datos procedentes de un origen XML, ya sea éste un archivo o una secuencia XML. DataSet se puede escribir como
XML conforme al consorcio World Wide Web (W3C), que incluye su esquema como esquema lenguaje de
definición de esquemas XML, independientemente del origen de los datos incluidos en DataSet . Puesto que el
formato nativo de serialización del DataSet es XML, es un medio excelente para mover datos de un nivel a otro,
por lo que DataSet es idóneo para usar datos y contextos de esquemas de interacción remota desde y hacia un
servicio Web XML. Para obtener más información, vea XML Documents and Data (Documentos y datos XML).
Vea también
Información general sobre ADO.NET
Directrices y opciones de tecnología de ADO.NET
10/02/2020 • 6 minutes to read • Edit Online
La plataforma de datos ADO.NET es una estrategia para varias versiones mediante la cual se reduce la cantidad de
código y el mantenimiento que necesitan los programadores con el fin de poder programar en modelos de datos
de entidades conceptuales. Esta plataforma incluye ADO.NET Entity Framework y tecnologías relacionadas.
Entity Framework
ADO.NET Entity Framework está diseñado para permitir que los desarrolladores creen aplicaciones de acceso a los
datos programando en un modelo de aplicación conceptual en lugar de programar directamente en un esquema
de almacenamiento relacional. El objetivo es reducir la cantidad de código y mantenimiento que se necesita para
las aplicaciones orientadas a datos. Para obtener más información, consulte ADO.NET Entity Framework.
Entity Data Model (EDM )
Entity Data Model (EDM) es una especificación de diseño que define datos de aplicación como conjuntos de
entidades y relaciones. Los datos de este modelo admiten la asignación relacional de objetos y la capacidad de
programación de los datos entre los límites de aplicación.
Servicios de objeto
Los servicios de objeto permiten a los programadores interactuar con los modelos conceptuales a través de un
conjunto de clases de Common Language Runtime (CLR). Estas clases se pueden generar de manera automática
desde el modelo conceptual o se pueden desarrollar de manera independiente para reflejar la estructura del
modelo conceptual. Los servicios de objeto también proporcionan compatibilidad de infraestructura con Entity
Framework, con servicios como administración de estados, seguimiento de cambios, resolución de identidad,
relaciones de carga y navegación, propagación de cambios de objeto a modificaciones de base de datos y
compatibilidad de creación de consultas para Entity SQL. Para más información, vea Información general de
Servicios de objeto (Entity Framework).
LINQ to Entities
LINQ to Entities es una implementación de Language-Integrated Query (LINQ) que permite a los desarrolladores
crear consultas fuertemente tipadas en el contexto de objeto de Entity Framework mediante expresiones de LINQ y
operadores de consulta estándar de LINQ. LINQ to Entities permite a los desarrolladores trabajar con un modelo
conceptual con una asignación flexible relacional de objetos entre Microsoft SQL Server y bases de datos de
terceros. Para obtener más información, vea LINQ to Entities.
Entity SQL
Entity SQL es un lenguaje de consulta basado en texto diseñado para interactuar con un Entity Data Model. Entity
SQL es un dialecto de SQL que contiene construcciones para la consulta en términos de conceptos de creación de
patrones de nivel superior, como herencia, tipos complejos y relaciones explícitas. Los programadores pueden
utilizar también Entity SQL directamente con los servicios de objetos. Para obtener más información, vea Entity
SQL Language.
EntityClient
EntityClient es un nuevo proveedor de datos .NET Framework utilizado para interactuar con un Entity Data Model.
EntityClient sigue el patrón de proveedor de datos .NET Framework de exponer objetos EntityConnection y
EntityCommand que devuelven EntityDataReader. EntityClient funciona con el lenguaje Entity SQL, que
proporciona una asignación flexible a los proveedores de datos específicos de almacenamiento. Para obtener más
información, consulte Proveedor de EntityClient para Entity Framework.
Herramientas de Entity Data Model
Entity Framework proporciona herramientas de línea de comandos, asistentes y diseñadores para facilitar la
compilación de aplicaciones EDM. El control EntityDataSource admite casos de enlace de datos basándose en el
EDM. La superficie de programación del control EntityDataSource es similar a otros controles de origen de datos de
Visual Studio. Para obtener más información, consulte ADO.NET Entity Data Model Tools.
LINQ a SQL
LINQ to SQL es una implementación relacional de objetos (OR/M) que le permite modelar una base de datos de
SQL Server mediante las clases de .NET Framework. LINQ to SQL permite consultar la base de datos mediante
LINQ, así como actualizar, insertar y eliminar datos de ella. LINQ to SQL admite transacciones, vistas y
procedimientos almacenados, proporcionando una forma fácil de integrar la validación de datos y las reglas de la
lógica de negocios en el modelo de datos. Puede usar Object Relational Designer (O/R Designer) para modelar
clases de entidad y asociaciones basadas en los objetos de una base de datos. Para obtener más información, vea
LINQ to SQL Tools en Visual Studio.
Consulte también
Información general sobre ADO.NET
Novedades de ADO.NET
LINQ y ADO.NET
10/02/2020 • 8 minutes to read • Edit Online
En la actualidad, muchos desarrolladores empresariales deben usar dos (o más) lenguajes de programación: un
lenguaje de alto nivel para los niveles de presentación y lógica C# empresarial (como Visual o Visual Basic) y un
lenguaje de consulta para interactuar con la base de datos (como TRANSACT-SQL). Esto requiere que el
programador tenga conocimientos de varios idiomas para ser efectivo y también causa discrepancias de idiomas
en el entorno de desarrollo. Por ejemplo, una aplicación que utiliza API de acceso a datos para ejecutar una
consulta en una base de datos especifica la consulta como un literal de cadena usando comillas. Esta cadena de
consulta no es legible para el compilador y no se comprueba si hay errores, como una sintaxis no válida o si
existen las columnas o filas a las que hace referencia. No hay ninguna comprobación de tipo de los parámetros de
consulta y tampoco hay compatibilidad con IntelliSense .
Language-Integrated Query (LINQ) permite a los desarrolladores crear consultas basadas en conjuntos en su
código de aplicación, sin tener que usar un lenguaje de consulta independiente. Puede escribir consultas LINQ en
varios orígenes de datos enumerables (es decir, un origen de datos que implementa la interfaz IEnumerable), como
estructuras de datos en memoria, documentos XML, bases de datos SQL y objetos DataSet. Aunque esos orígenes
de datos enumerables se implementan de varias formas, todos revelan las mismas construcciones de lenguaje y
sintaxis. Como las consultas se pueden formar en el lenguaje de programación mismo, no es necesario utilizar otro
lenguaje de consultas que esté incrustado como literales de cadena que el compilador no pueda entender o
comprobar. La integración de consultas en el lenguaje de programación también permite que los programadores
de Visual Studio sean más productivos al proporcionar comprobación de sintaxis y tipos en tiempo de
compilación, y IntelliSense . Estas características reducen la necesidad de depuración y corrección de errores de
consultas.
La transferencia de datos de las tablas de SQL a objetos de memoria a menudo es una tarea tediosa y propensa a
errores. El proveedor LINQ implementado por LINQ to DataSet y LINQ to SQL convierte los datos de origen en
colecciones de objetos basadas en IEnumerable. El programador siempre ve los datos como una colección de
IEnumerable cuando se realiza la consulta y la actualización. Se proporciona compatibilidad completa con
IntelliSense para escribir consultas en esas colecciones.
Hay tres tecnologías de ADO.NET Language Integrated Query (LINQ) independientes: LINQ to DataSet, LINQ to
SQLy LINQ to Entities. LINQ to DataSet proporciona consultas más enriquecidas y optimizadas en el DataSet y
LINQ to SQL le permite consultar directamente esquemas de base de datos de SQL Server y LINQ to Entities le
permite consultar una Entity Data Model.
El siguiente diagrama proporciona una visión general de cómo se relacionan las tecnologías ADO.NET LINQ con
lenguajes de programación de alto nivel y orígenes de datos habilitados para LINQ.
Para obtener más información sobre LINQ, vea Language Integrated Query (LINQ).
En las secciones siguientes se proporciona más información acerca de LINQ to DataSet, LINQ to SQLy LINQ to
Entities.
LINQ to DataSet
El DataSet es un elemento clave del modelo de programación desconectado en el que se basa ADO.NET y se usa
ampliamente. LINQ to DataSet permite a los desarrolladores crear funciones de consulta más enriquecidas en
DataSet mediante el mismo mecanismo de formulación de consultas que está disponible para muchos otros
orígenes de datos. Para más información, vea LINQ to DataSet.
LINQ a SQL
LINQ to SQL es una herramienta útil para programadores que no requieren la asignación a un modelo conceptual.
Con LINQ to SQL, puede utilizar el modelo de programación LINQ directamente sobre el esquema de la base de
datos existente. LINQ to SQL permite a los desarrolladores generar .NET Framework clases que representan datos.
En lugar de la asignación a un modelo de datos conceptual, esas clases generadas se asignan directamente a tablas
de bases de datos, vistas, procedimientos almacenados y funciones definidas por el usuario.
Con LINQ to SQL, los desarrolladores pueden escribir código directamente en el esquema de almacenamiento
mediante el mismo modelo de programación de LINQ que las colecciones en memoria y el DataSet, además de
otros orígenes de datos como XML. Para obtener más información, consulta LINQ to SQL.
LINQ to Entities
La mayor parte de las aplicaciones se escriben actualmente utilizando bases de datos relacionales. En algún punto,
estas aplicaciones tendrán que interactuar con los datos representados en un formato relacional. Los esquemas de
base de datos no siempre son ideales para crear aplicaciones y los modelos conceptuales de aplicación no son
iguales que los modelos lógicos de bases de datos. La Entity Data Model es un modelo de datos conceptual que se
puede usar para modelar los datos de un dominio determinado para que las aplicaciones puedan interactuar con
los datos como objetos. Para obtener más información, consulte ADO.NET Entity Framework.
A través del modelo Entity Data Model, los datos relacionales se exponen como objetos en el entorno .NET. Esto
hace de la capa de objetos un objetivo idóneo para la compatibilidad con LINQ, ya que permite a los
programadores formular consultas en la base de datos con el lenguaje usado para compilar la lógica empresarial.
Esta funcionalidad se conoce como LINQ to Entities. Para obtener más información, vea LINQ to Entities.
Consulte también
LINQ to DataSet
LINQ to SQL
LINQ to Entities
Language-Integrated Query (LINQ)
Información general sobre ADO.NET
Proveedores de datos .NET Framework
08/01/2020 • 17 minutes to read • Edit Online
Un proveedor de datos de .NET Framework se utiliza para conectarse a una base de datos, ejecutar comandos y
recuperar resultados. Esos resultados se procesan directamente, se colocan en un DataSet con el fin de que el
usuario pueda verlos cuando los necesite, se combinan con datos de varios orígenes o se utilizan de forma remota
entre niveles. .NET Framework proveedores de datos son ligeros, creando una capa mínima entre el origen de
datos y el código, lo que aumenta el rendimiento sin sacrificar la funcionalidad.
En la tabla siguiente se enumeran los proveedores de datos que se incluyen en el .NET Framework.
P RO VEEDO R DE DATO S DE . N ET F RA M EW O RK ( . N ET
F RA M EW O RK DATA P RO VIDER) DESC RIP C IÓ N
Proveedor de datos .NET Framework para SQL Server Proporciona acceso de datos para Microsoft SQL Server.
Utiliza el espacio de nombres System.Data.SqlClient .
Proveedor de datos .NET Framework para OLE DB Para orígenes de datos que se exponen mediante OLE DB.
Utiliza el espacio de nombres System.Data.OleDb .
Proveedor de datos de .NET Framework para ODBC Para orígenes de datos que se exponen mediante ODBC.
Utiliza el espacio de nombres System.Data.Odbc .
Proveedor de datos de .NET Framework para Oracle Para orígenes de datos de Oracle. El proveedor de datos de
.NET Framework para Oracle es compatible con la versión
8.1.7 y posteriores del software cliente de Oracle y utiliza el
espacio de nombres System.Data.OracleClient.
Proveedor para EntityClient Proporciona acceso a datos para las aplicaciones de Entity
Data Model (EDM). Utiliza el espacio de nombres
System.Data.EntityClient .
.NET Framework proveedor de datos para SQL Server Proporciona acceso a datos para Microsoft SQL Server
Compact 4,0. Compact 4,0. Usa el espacio de nombres
System.Data.SqlServerCe .
Además de las clases principales enumeradas en la tabla anterior de este documento, un proveedor de datos de
.NET Framework también contiene las clases que se muestran en la tabla siguiente.
NOTE
El proveedor de datos .NET Framework para ODBC tiene una arquitectura similar a la del proveedor de datos .NET
Framework para OLE DB; por ejemplo, llama a un componente de servicio ODBC.
Comparación del proveedor de datos .NET Framework para SQL Server y el proveedor de datos .NET Framework
para OLE DB
El proveedor de datos de .NET Framework para las clases de SQL Server se encuentra en el espacio de nombres
System.Data.SqlClient.
El proveedor de datos de .NET Framework para SQL Server admite transacciones locales y distribuidas. Para las
transacciones distribuidas, el proveedor de datos de .NET Framework para SQL Server, de forma predeterminada,
se da de alta automáticamente en una transacción y obtiene los detalles de la transacción de los servicios de
componentes de Windows o System.Transactions. Para obtener más información, consulte transacciones y
simultaneidad.
En el siguiente ejemplo de código se muestra cómo puede incluir el espacio de nombres System.Data.SqlClient
en sus aplicaciones.
Imports System.Data.SqlClient
using System.Data.SqlClient;
C O N T RO L A DO R P RO VEEDO R
NOTE
No se recomienda utilizar una base de datos de Access (jet) como origen de datos para las aplicaciones multiproceso, como
las aplicaciones ASP.NET. Si debe usar jet como origen de datos para una aplicación de ASP.NET, tenga en cuentan que las
aplicaciones de ASP.NET que se conectan a una base de datos de Access pueden encontrar problemas de conexión.
El proveedor de datos de .NET Framework para OLE DB no es compatible con las interfaces OLE DB versión 2,5.
OLE DB proveedores que requieran compatibilidad con las interfaces de OLE DB 2,5 no funcionarán correctamente
con el proveedor de datos de .NET Framework para OLE DB. Entre ellos se incluye el proveedor Microsoft OLE DB
para Exchange y el proveedor Microsoft OLE DB para la publicación en Internet.
El proveedor de datos de .NET Framework para OLE DB no funciona con el proveedor de OLE DB para ODBC
(MSDASQL). Para obtener acceso a un origen de datos ODBC mediante ADO.NET, use el proveedor de datos de
.NET Framework para ODBC.
.NET Framework proveedor de datos para OLE DB clases se encuentran en el espacio de nombres
System.Data.OleDb. En el siguiente ejemplo de código se muestra cómo puede incluir el espacio de nombres
System.Data.OleDb en sus aplicaciones.
Imports System.Data.OleDb
using System.Data.OleDb;
C O N T RO L A DO R
SQL Server
.NET Framework proveedor de datos para las clases ODBC se encuentran en el espacio de nombres
System.Data.Odbc.
En el siguiente ejemplo de código se muestra cómo puede incluir el espacio de nombres System.Data.Odbc en sus
aplicaciones.
Imports System.Data.Odbc
using System.Data.Odbc;
NOTE
El proveedor de datos de .NET Framework para ODBC requiere MDAC 2,6 o una versión posterior, y se recomienda MDAC
2,8 SP1. Puede descargar MDAC 2,8 SP1 desde el centro de descarga de Microsoft.
Imports System.Data
Imports System.Data.OracleClient
using System.Data;
using System.Data.OracleClient;
P RO VEEDO R N OTA S
Proveedor de datos .NET Framework para SQL Server Se recomienda para las aplicaciones de nivel intermedio que
usan Microsoft SQL Server.
Proveedor de datos .NET Framework para OLE DB Por SQL Server, se recomienda el proveedor de datos .NET
Framework para SQL Server en lugar de este proveedor.
Proveedor de datos de .NET Framework para ODBC Recomendado para aplicaciones de un único nivel y de nivel
medio que utilizan orígenes de datos de ODBC.
Proveedor de datos de .NET Framework para Oracle Recomendado para aplicaciones de un único nivel y de nivel
medio que utilizan orígenes de datos de Oracle.
Vea también
Información general sobre ADO.NET
Recuperar y modificar datos en ADO.NET
Objetos DataSet de ADO.NET
05/02/2020 • 6 minutes to read • Edit Online
El objeto DataSet es fundamental para admitir escenarios de datos distribuidos y desconectados con ADO.NET. El
DataSet es una representación residente en memoria de los datos que proporciona un modelo de programación
relacional coherente independientemente del origen de datos. Se puede utilizar con muchos y distintos orígenes de
datos, con datos XML o para administrar datos locales de la aplicación. El DataSet representa un conjunto
completo de datos, incluidas las tablas relacionadas, las restricciones y las relaciones entre las tablas. En la
ilustración siguiente se muestra el modelo de objetos DataSet .
DataTableCollection
Un conjunto de ADO.net contiene una colección de cero o más tablas representadas por objetos DataTable. La
DataTableCollection contiene todos los objetos DataTable de un DataSet .
Un DataTable se define en el espacio de nombres System.Data y representa una única tabla de datos residentes en
memoria. Contiene una colección de columnas representadas por una DataColumnCollection, así como
restricciones representadas por una ConstraintCollection, que juntas definen el esquema de la tabla. Un objeto
DataTable también contiene una colección de filas representada por el DataRowCollection, que contiene los datos
de la tabla. Una DataRow conserva, junto con su estado actual, sus versiones actual y original para identificar los
cambios en los valores almacenados en la fila.
Clase DataView
Una DataView le permite crear diferentes vistas de los datos almacenados en una DataTable, una capacidad que
suele utilizarse en aplicaciones de enlace a datos. Mediante DataView puede exponer los datos de una tabla con
distintos criterios de ordenación y filtrar los datos por el estado de fila o basándose en una expresión de filtro. Para
obtener más información, vea las vistasde datos.
DataRelationCollection
Un conjunto de objetos contiene relaciones en su objeto DataRelationCollection. Una relación, representada por el
objeto DataRelation, asocia las filas de un DataTable con las filas de otra DataTable . Las relaciones son análogas a
las rutas de acceso de unión que podrían existir entre columnas de claves principales y externas en una base de
datos relacional. Una DataRelation identifica las columnas coincidentes en dos tablas de un DataSet .
Las relaciones permiten la navegación de una tabla a otra en un conjunto de DataSet . Los elementos esenciales
de una DataRelation son el nombre de la relación, el nombre de las tablas relacionadas y las columnas
relacionadas de cada tabla. Es posible crear relaciones con más de una columna por tabla si se especifica una
matriz de objetos DataColumn como columnas de claves. Cuando se agrega una relación a la
DataRelationCollection, opcionalmente se puede Agregar un UniqueKeyConstraint y una
ForeignKeyConstraint para aplicar restricciones de integridad cuando se realicen cambios en los valores de
columna relacionados.
Para obtener más información, vea agregar objetos DataRelation.
XML
Puede rellenar un conjunto de documentos a partir de una secuencia o un documento XML. Puede utilizar la
secuencia o el documento XML para proporcionar al conjunto de datos, información de esquema o ambas cosas.
La información suministrada desde la secuencia o el documento XML puede combinarse con los datos existentes o
la información de esquema que ya está presente en el conjunto de datos. Para obtener más información, vea Using
XML in a DataSet (Usar XML en un conjunto de datos).
ExtendedProperties
Todos los conjuntos de propiedades, DataTable y DataColumn tienen una propiedad ExtendedProper ties .
ExtendedProper ties es un Proper tyCollection en el que puede colocar información personalizada, como la
instrucción SELECT que se usó para generar el conjunto de resultados o la hora a la que se generaron los datos. La
colección ExtendedProper ties se conserva con la información de esquema del conjunto de datos.
LINQ to DataSet
LINQ to DataSet proporciona funciones de consulta integradas en el lenguaje para los datos desconectados
almacenados en un conjunto de datos. LINQ to DataSet usa la sintaxis estándar de LINQ y proporciona
comprobación de sintaxis en tiempo de compilación, tipos estáticos y compatibilidad con IntelliSense cuando se
usa el IDE de Visual Studio.
Para más información, vea LINQ to DataSet.
Vea también
Información general sobre ADO.NET
Objetos DataSet, DataTable y DataView
Recuperar y modificar datos en ADO.NET
Ejecución en paralelo en ADO.NET
05/02/2020 • 10 minutes to read • Edit Online
La ejecución en paralelo en el .NET Framework es la capacidad de ejecutar una aplicación en un equipo que tiene
varias versiones de .NET Framework instaladas, exclusivamente con la versión para la que se compiló la aplicación.
Para obtener información detallada sobre la configuración de la ejecución en paralelo, vea ejecución en paralelo.
Una aplicación compilada con una versión de la .NET Framework puede ejecutarse en una versión diferente de la
.NET Framework. Sin embargo, se recomienda compilar una versión de la aplicación para cada versión instalada de
la .NET Framework y ejecutarlas por separado. En cualquier escenario, debe tener en cuenta los cambios en
ADO.NET entre versiones que pueden afectar a la compatibilidad con versiones posteriores o a la compatibilidad
con versiones anteriores de la aplicación.
Ejecución de SqlCommand
A partir de la versión 1,1 de .NET Framework, se ha cambiado la forma en que ExecuteReader ejecuta los comandos
en el origen de datos.
En el .NET Framework versión 1,0, ExecuteReader ejecutado todos los comandos en el contexto del procedimiento
almacenado sp_executesql . Como resultado, los comandos que influyen en el estado de la conexión (Activar
NOCOUNT, por ejemplo) sólo se aplican a la ejecución del comando actual. Mientras la conexión permanece
abierta, los comandos que se ejecutan posteriormente no modifican el estado de la conexión.
En la .NET Framework versión 1,1 y posteriores, ExecuteReader solo ejecuta un comando en el contexto del
procedimiento almacenado sp_executesql si el comando contiene parámetros, lo que proporciona una ventaja de
rendimiento. Como consecuencia, si un comando que influye en el estado de la conexión se incluye en un comando
sin parámetros, modifica el estado de la conexión de todos los comandos posteriores que se ejecuten mientras la
conexión esté abierta.
Tomemos como ejemplo el siguiente lote de comandos, que se ejecuta en una llamada a ExecuteReader.
En la .NET Framework versión 1,1 y posteriores, NOCOUNT permanecerá en para los comandos posteriores que se
ejecuten mientras la conexión esté abierta. En la versión .NET Framework 1,0, NOCOUNT solo está activado para la
ejecución del comando actual.
Este cambio puede afectar a la compatibilidad con versiones anteriores y posteriores de la aplicación si depende
del comportamiento de ExecuteReader para cualquiera de las versiones de la .NET Framework.
En el caso de las aplicaciones que se ejecutan en versiones anteriores y posteriores de la .NET Framework, puede
escribir el código para asegurarse de que el comportamiento es el mismo independientemente de la versión en la
que se ejecuta. Si desea asegurarse de que un comando modifica el estado de la conexión para todos los comandos
que se ejecuten posteriormente, se recomienda ejecutar el comando usando ExecuteNonQuery. Si desea
asegurarse de que un comando no modifica el estado de la conexión para todos los comandos que se ejecuten
posteriormente, se recomienda incluir los comandos para restablecer el estado de la conexión en el comando. Por
ejemplo:
SET NOCOUNT ON;
SELECT * FROM dbo.Customers;
SET NOCOUNT OFF;
Vea también
Información general sobre ADO.NET
Recuperar y modificar datos en ADO.NET
ejemplos de código ADO.NET
21/03/2020 • 15 minutes to read • Edit Online
Los listados de código de esta página muestran cómo recuperar datos de una base de datos mediante las
siguientes tecnologías de ADO.NET:
Proveedores de datos ADO.NET:
SqlClient System.Data.SqlClient ()
OleDb System.Data.OleDb ()
Odbc System.Data.Odbc ()
OracleClient System.Data.OracleClient ()
ADO.NET Entity Framework:
LINQ to Entities
ObjectQuery con establecimiento de tipos
EntityClient System.Data.EntityClient ()
LINQ a SQL
class Program
{
static void Main()
{
string connectionString =
"Data Source=(local);Initial Catalog=Northwind;"
+ "Integrated Security=true";
Imports System.Data
Imports System.Data.SqlClient
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Console.ReadLine()
End Using
End Sub
End Class
OleDb
En el código de este ejemplo se asume que puede conectarse a la base de datos de ejemplo Northwind de
Microsoft Access. El código crea OleDbCommand para seleccionar filas de la tabla Products, que añade
OleDbParameter para limitar los resultados a las filas con un UnitPrice mayor que el valor de parámetro
especificado, en este caso 5. OleDbConnection se abre dentro de un bloque using , que garantiza que los recursos
se cierran y se eliminan cuando termina la ejecución del código. El código ejecuta el comando utilizando
OleDbDataReader y muestra los resultados en la ventana de la consola.
using System;
using System.Data;
using System.Data.OleDb;
class Program
{
static void Main()
{
// The connection string assumes that the Access
// Northwind.mdb is located in the c:\Data folder.
string connectionString =
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
+ "c:\\Data\\Northwind.mdb;User Id=admin;Password=;";
Imports System.Data
Imports System.Data.OleDb
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Console.ReadLine()
End Using
End Sub
End Class
Odbc
En el código de este ejemplo se asume que puede conectarse a la base de datos de ejemplo Northwind de
Microsoft Access. El código crea OdbcCommand para seleccionar filas de la tabla Products, que añade
OdbcParameter para limitar los resultados a las filas con un UnitPrice mayor que el valor de parámetro
especificado, en este caso 5. Se OdbcConnection abre dentro using de un bloque, lo que garantiza que los
recursos se cierran y se eliminan cuando se cierra el código. El código ejecuta el comando utilizando
OdbcDataReader y muestra los resultados en la ventana de la consola.
using System;
using System.Data;
using System.Data.Odbc;
class Program
{
static void Main()
{
// The connection string assumes that the Access
// Northwind.mdb is located in the c:\Data folder.
string connectionString =
"Driver={Microsoft Access Driver (*.mdb)};"
+ "Dbq=c:\\Data\\Northwind.mdb;Uid=Admin;Pwd=;";
Imports System.Data
Imports System.Data.Odbc
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Console.ReadLine()
End Using
End Sub
End Class
OracleClient
En el código de este ejemplo se presupone una conexión a DEMO.CUSTOMER en un servidor Oracle. También debe
agregarse una referencia a System.Data.OracleClient.dll. El código devuelve los datos en OracleDataReader.
using System;
using System.Data;
using System.Data.OracleClient;
class Program
{
static void Main()
{
string connectionString =
"Data Source=ThisOracleServer;Integrated Security=yes;";
string queryString =
"SELECT CUSTOMER_ID, NAME FROM DEMO.CUSTOMER";
using (OracleConnection connection =
new OracleConnection(connectionString))
{
OracleCommand command = connection.CreateCommand();
command.CommandText = queryString;
try
{
connection.Open();
while (reader.Read())
{
Console.WriteLine("\t{0}\t{1}",
reader[0], reader[1]);
}
reader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
Option Explicit On
Option Strict On
Imports System.Data
Imports System.Data.OracleClient
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Using
End Sub
End Class
class LinqSample
{
public static void ExecuteQuery()
{
using (NorthwindEntities context = new NorthwindEntities())
{
try
{
var query = from category in context.Categories
select new
{
categoryID = category.CategoryID,
categoryName = category.CategoryName
};
Option Explicit On
Option Strict On
Imports System.Linq
Imports System.Data.Objects
Imports NorthwindModel
Class LinqSample
Public Shared Sub ExecuteQuery()
Using context As NorthwindEntities = New NorthwindEntities()
Try
Dim query = From category In context.Categories _
Select New With _
{ _
.categoryID = category.CategoryID, _
.categoryName = category.CategoryName _
}
using System;
using System.Data.Objects;
using NorthwindModel;
class ObjectQuerySample
{
public static void ExecuteQuery()
{
using (NorthwindEntities context = new NorthwindEntities())
{
ObjectQuery<Categories> categoryQuery = context.Categories;
Option Explicit On
Option Strict On
Imports System.Data.Objects
Imports NorthwindModel
Class ObjectQuerySample
Public Shared Sub ExecuteQuery()
Using context As NorthwindEntities = New NorthwindEntities()
Dim categoryQuery As ObjectQuery(Of Categories) = context.Categories
EntityClient
El código de este ejemplo usa EntityCommand para ejecutar una consulta Entity SQL. Esta consulta devuelve una
lista de registros que representan instancias del tipo de entidad Categories. Se usa EntityDataReader para obtener
acceso a los registros de datos del conjunto de resultados. Para obtener más información, consulte Proveedor de
EntityClient para Entity Framework.
using System;
using System.Data;
using System.Data.Common;
using System.Data.EntityClient;
using NorthwindModel;
class EntityClientSample
{
public static void ExecuteQuery()
{
string queryString =
@"SELECT c.CategoryID, c.CategoryName
FROM NorthwindEntities.Categories AS c";
Imports System.Data
Imports System.Data.Common
Imports System.Data.EntityClient
Imports NorthwindModel
Class EntityClientSample
Public Shared Sub ExecuteQuery()
Dim queryString As String = _
"SELECT c.CategoryID, c.CategoryName " & _
"FROM NorthwindEntities.Categories AS c"
Try
conn.Open()
Using query As EntityCommand = _
New EntityCommand(queryString, conn)
Using rdr As DbDataReader = _
query.ExecuteReader(CommandBehavior.SequentialAccess)
While rdr.Read()
Console.WriteLine(vbTab & "{0}" & vbTab & "{1}", _
rdr(0), rdr(1))
End While
End Using
End Using
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Using
End Sub
End Class
LINQ a SQL
El código de este ejemplo usa una consulta LINQ para devolver los datos como objetos Categories, que se
proyectan como un tipo anónimo que contiene solo las propiedades CategoryID y CategoryName. Este ejemplo se
basa en el contexto de datos Northwind. Para obtener más información, consulte Introducción.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Northwind;
class LinqSqlSample
{
public static void ExecuteQuery()
{
using (NorthwindDataContext db = new NorthwindDataContext())
{
try
{
var query = from category in db.Categories
select new
{
categoryID = category.CategoryID,
categoryName = category.CategoryName
};
Option Explicit On
Option Strict On
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports Northwind
Class LinqSqlSample
Public Shared Sub ExecuteQuery()
Using db As NorthwindDataContext = New NorthwindDataContext()
Try
Dim query = From category In db.Categories _
Select New With _
{ _
.categoryID = category.CategoryID, _
.categoryName = category.CategoryName _
}
Para escribir una aplicación de ADO.NET segura es necesario algo más que evitar los errores de codificación más
comunes, como no validar los datos proporcionados por el usuario. Una aplicación que tiene acceso a datos tiene
muchos puntos débiles potenciales que un agresor puede aprovechar para obtener, manipular o destruir datos
confidenciales. Por eso es importante comprender todos los aspectos de la seguridad, desde el proceso de
modelo de amenazas durante la fase de diseño de su aplicación hasta la implementación y el posterior
mantenimiento.
.NET Framework ofrece muchas clases, servicios y herramientas que resultan muy útiles para proteger y
administrar aplicaciones de base de datos. Common Language Runtime (CLR) proporciona un entorno de
seguridad de tipos en el que ejecutar el código, junto con la seguridad de acceso del código (CAS) para restringir
aún más los permisos del código administrado. Si se siguen las recomendaciones de codificación del acceso
seguro a datos, se reduce el daño que podría provocar un posible agresor.
El código seguro no protege de la vulnerabilidad de seguridad que provoca el propio usuario cuando trabaja con
recursos no administrados como bases de datos. La mayoría de las bases de datos, como SQL Server, tienen sus
propios sistemas de seguridad, que contribuyen a mejorarla cuando se implementan correctamente. Sin
embargo, incluso un origen de datos con un robusto sistema de seguridad puede sufrir un ataque si no se ha
configurado correctamente.
Esta sección
Información general sobre seguridad
Proporciona recomendaciones para diseñar aplicaciones seguras de ADO.NET.
Acceso seguro a datos
Describe cómo trabajar con datos de un origen de datos protegido.
Aplicaciones cliente seguras
Describe consideraciones de seguridad para aplicaciones cliente.
Seguridad de acceso del código y ADO.NET
Describe cómo se puede proteger el código de ADO.NET mediante la seguridad de acceso del código. También
explica cómo trabajar con confianza parcial.
Privacidad y seguridad de datos
Describe las opciones de cifrado para las aplicaciones de ADO.NET.
Secciones relacionadas
Seguridad de SQL Server
Describe las características de seguridad de SQL Server desde la perspectiva del desarrollador.
Consideraciones de seguridad
Describe la seguridad de las aplicaciones de Entity Framework.
Seguridad
Contiene vínculos a temas en los que describen todos los aspectos de la seguridad en .NET.
Herramientas de seguridad
Herramientas de .NET Framework para proteger y administrar las directivas de seguridad.
Recursos para crear aplicaciones seguras
Proporciona vínculos a temas para crear aplicaciones seguras.
Bibliografía sobre seguridad
Proporciona vínculos a recursos externos disponibles en línea e impresos.
Vea también
ADO.NET
Información general sobre ADO.NET
Introducción sobre la seguridad
08/01/2020 • 11 minutes to read • Edit Online
La protección de una aplicación es un proceso continuo. Es prácticamente imposible que se llegue a un momento
en el que un programador pueda garantizar que una aplicación es invulnerable ante todo tipo de ataques, ya que
no es posible predecir los tipos de ataques que surgirán en un futuro con las nuevas tecnologías. Al contrario, el
hecho de que nadie haya detectado (o publicado) aún brechas de seguridad en un sistema, no quiere decir que
éstas no existan o no puedan existir en un futuro. Por lo tanto, es necesario planificar la seguridad durante la fase
de diseño del proyecto, así como la forma en que se mantendrá la seguridad durante el ciclo de vida de la
aplicación.
Diseñar la seguridad
Uno de los mayores problemas de la programación de aplicaciones seguras es el hecho de que a menudo la
seguridad no se planifica con antelación, sino que se implementa cuando el código de un proyecto se ha
completado. Esta práctica genera aplicaciones poco seguras, ya que no se ha dedicado suficiente tiempo a entender
qué hace que una aplicación sea segura.
La implementación de la seguridad de última hora conduce a más errores, ya que el software se interrumpe según
las nuevas restricciones o se tiene que volver a escribir para adaptarse a la funcionalidad imprevista. Cada línea de
código revisado incluye la posibilidad de insertar un error nuevo. En ese sentido, debe tener en cuenta la seguridad
al principio del proceso de programación de manera que se desarrolle junto con la programación de nuevas
características.
Modelo de amenazas
No se puede proteger un sistema de ataques a menos que comprenda todos los posibles ataques a los que está
expuesto. El proceso de evaluación de las amenazas de seguridad, denominados modelado de amenazas, es
necesario para determinar la probabilidad y las consecuencias de las infracciones de seguridad en la aplicación
ADO.net.
El modelo de amenazas está compuesto de tres pasos principales: comprender la visión del adversario, caracterizar
la seguridad del sistema y determinar las amenazas.
El modelo de amenazas es un enfoque repetitivo en la evaluación de las vulnerabilidades de la aplicación, que se
usa para detectar las vulnerabilidades más peligrosas, ya que éstas exponen los datos más confidenciales. Una vez
identificadas, las vulnerabilidades se clasifican en función de su gravedad y se crea un conjunto con prioridades de
medidas para contrarrestar las amenazas.
Para obtener más información, vea los siguientes recursos:
El sitio de modelado de amenazas en el portal de ingeniería de Los recursos de esta página le ayudarán a entender el proceso
seguridad de modelo de amenazas y a desarrollar modelos de amenazas
que puede usar para proteger sus propias aplicaciones
Seguridad de acceso del código y ADO.NET Describe las interacciones entre la seguridad de acceso del
código, la seguridad basada en funciones y los entornos de
confianza parcial desde la perspectiva de una aplicación
ADO.NET.
REC URSO DESC RIP C IÓ N
Seguridad de acceso del código Contiene vínculos a temas adicionales que describen CAS en
.NET Framework.
Recomendaciones para las estrategias de acceso a datos Proporciona recomendaciones para obtener acceso a datos y
realizar operaciones de base de datos.
Prácticas recomendadas de la Directiva de seguridad Proporciona vínculos a temas que describen cómo administrar
la directiva de seguridad.
Vea también
Proteger aplicaciones de ADO.NET
Seguridad en .NET
Seguridad de SQL Server
Información general sobre ADO.NET
Acceso seguro a datos
08/01/2020 • 10 minutes to read • Edit Online
Para escribir código de ADO.NET seguro, debe comprender los mecanismos de seguridad disponibles en el
almacén de datos subyacente o en la base de datos. También debe tener en cuenta las implicaciones en la
seguridad de otras características o componentes que pudieran incluirse en la aplicación.
Recomendaciones para las estrategias de acceso a datos Proporciona recomendaciones para obtener acceso a datos y
realizar operaciones de base de datos.
Información general sobre la seguridad de SQL Server Describe la arquitectura de seguridad de SQL Server.
Modificación de datos con procedimientos almacenados Describe cómo especificar parámetros y cómo obtener un
valor devuelto.
Administración de permisos con procedimientos almacenados Describe cómo usar procedimientos almacenados de SQL
en SQL Server Server para encapsular el acceso a datos.
Introducción a los ataques de scripts Describe cómo protegerse de ataques mediante scripts o
instrucciones SQL.
Controlar y generar excepciones en .NET Describe las formas básicas Try/Catch/Finally del control de
excepciones estructurado.
Procedimientos recomendados para excepciones Describe los procedimientos recomendados para controlar
excepciones.
Consideraciones de seguridad e instrucciones para el acceso Describe técnicas de seguridad para Access 2007 como el
2007 cifrado de archivos, la administración de contraseñas, la
conversión de bases de datos a los nuevos formatos ACCDB y
ACCDE y el uso de otras opciones de seguridad.
Introducción a Access 2010 Security Proporciona información general sobre las características de
seguridad que ofrece Access 2010.
Enterprise Services
COM+ incluye su propio modelo de seguridad que se basa en las cuentas de Windows NT y en la suplantación de
procesos y subprocesos. El espacio de nombres System.EnterpriseServices proporciona contenedores que
permiten a las aplicaciones .NET integrar código administrado con servicios de seguridad COM+ mediante la clase
ServicedComponent.
Para obtener más información, vea el siguiente recurso.
Interoperating with Unmanaged Code (Interoperar con código Contiene temas que describen cómo exponer componentes
no administrado) COM a .NET Framework y cómo exponer componentes de
.NET Framework a COM.
Interoperabilidad COM avanzada Contiene temas avanzados como, por ejemplo, los
ensamblados de interoperabilidad principal, los subprocesos y
el cálculo de referencias personalizado.
Vea también
Proteger aplicaciones de ADO.NET
Seguridad de SQL Server
Recomendaciones para las estrategias de acceso a datos
Proteger la información de conexión
Generadores de cadenas de conexión
Información general sobre ADO.NET
Aplicaciones cliente seguras
23/10/2019 • 6 minutes to read • Edit Online
Por lo general las aplicaciones constan de varios elementos que deben estar protegidos ante las vulnerabilidades
que pueden provocar pérdidas de datos o poner en peligro el sistema de cualquier otro modo. La creación de
interfaces de usuario seguras puede impedir un gran número de problemas ya que bloquea a los atacantes antes
de que puedan tener acceso a los datos o a los recursos del sistema.
IMPORTANT
También debe validar los datos introducidos por el usuario en el origen de datos, además de la aplicación cliente. Un atacante
puede evitar la aplicación y atacar directamente al origen de datos.
Proteger los servicios Web XML creados con ASP.NET Describe cómo implementar la seguridad en un servicio Web
ASP.NET.
Introducción a los ataques de scripts Describe cómo protegerse ante ataques de script, que
intentan insertar caracteres malintencionados en una página
web.
Prácticas de seguridad básicas para aplicaciones Web Información general sobre la seguridad y vínculos para
profundizar en el tema.
Comunicación remota
La comunicación remota de .NET permite crear fácilmente aplicaciones ampliamente distribuidas, tanto si los
componentes de las aplicaciones están todos en un equipo como si están repartidos por el mundo. Puede generar
aplicaciones cliente que utilizan los objetos de otros procesos en el mismo equipo o en cualquier otro equipo que
se puede alcanzar a través de su red. También puede usar .NET Remoting para comunicar con otros dominios de
aplicación en el mismo proceso.
Consideraciones sobre seguridad y comunicación remota Describe problemas de seguridad con objetos protegidos y
con el cruce entre dominios de aplicación.
Vea también
Proteger aplicaciones de ADO.NET
Recomendaciones para las estrategias de acceso a datos
Proteger aplicaciones
Proteger la información de conexión
Información general sobre ADO.NET
Seguridad de acceso del código y ADO.NET
21/03/2020 • 25 minutes to read • Edit Online
.NET Framework ofrece seguridad basada en roles y seguridad de acceso del código (CAS); ambas se implementan
utilizando una infraestructura común proporcionada por Common Language Runtime (CLR). En el mundo del
código no administrado, la mayoría de las aplicaciones se ejecutan mediante los permisos del usuario o de la
entidad de seguridad. Por consiguiente, los sistemas de equipos pueden resultar dañados y se pueden poner en
peligro los datos privados si un usuario con un nivel elevado de privilegios ejecuta software malintencionado o
que contenga errores.
El código administrado que se ejecuta en .NET Framework, sin embargo, incluye seguridad de acceso del código,
que se aplica únicamente al código. El permiso para que el código se ejecute o no depende de su origen o de otros
aspectos de la identidad del código, y no solo de la identidad de la entidad de seguridad. De esta forma, se reduce
la probabilidad de que se utilice el código de manera incorrecta.
NOTE
El código que se ejecuta en el CLR no se puede conceder permisos a sí mismo. Por ejemplo, el código puede solicitar y que
se le asignen menos permisos de los que concede una directiva de seguridad, pero no se le concederán más permisos. A la
hora de conceder permisos, comience sin ningún permiso y agregue los mínimos permisos necesarios para la tarea concreta
que se lleva a cabo. Si se comienza con todos los permisos y posteriormente se deniegan permisos de forma individual, se
obtienen aplicaciones poco seguras que pueden contener vulnerabilidades de seguridad no intencionadas debido a la
concesión de más permisos de los que son necesarios. Para obtener más información, consulte Configuración de la directiva
de seguridad y la administración de directivasde seguridad .
Ensamblados
Los ensamblados componen la unidad fundamental de implementación, control de versiones, reutilización, ámbito
de activación y permisos de seguridad en una aplicación de .NET Framework. Un ensamblado proporciona una
colección de tipos y recursos creados para funcionar en conjunto y formar una unidad lógica de funcionalidad. En
CLR, un tipo no existe si no es en el contexto de un ensamblado. Para obtener más información sobre cómo crear e
implementar ensamblados, vea Programación con ensamblados.
Ensamblados con nombre seguro
Un nombre seguro, o firma digital, consta de la identidad del ensamblado, que incluye su nombre de texto sencillo,
el número de versión, la información de referencia cultural (si se proporciona), así como una clave pública y una
firma digital. La firma digital se genera a partir de un archivo de ensamblado que usa la clave privada
correspondiente. El archivo de ensamblado contiene el manifiesto del ensamblado, que contiene los nombres y
códigos hash de todos los archivos que forman el ensamblado.
La asignación de un nombre seguro al ensamblado proporciona a una aplicación o a un componente una
identidad única que puede usar otro software para referirse a ella de manera explícita. La asignación de nombres
seguros protege a los ensamblados de la suplantación por parte de un ensamblado que contenga código
malintencionado. También garantiza la coherencia entre las diferentes versiones de un componente. Debe usar
nombres seguros en los ensamblados que se van a implementar en la caché global de ensamblados (GAC). Para
obtener más información, vea Crear y utilizar ensamblados con nombre seguro.
Se hereda de DBDataPermissionAttribute.
Sintaxis de ConnectionString
En el siguiente ejemplo se muestra cómo se utiliza el elemento connectionStrings de un archivo de configuración
para permitir únicamente el uso de una determinada cadena de conexión. Consulte Cadenas de conexión para
obtener más información sobre cómo almacenar y recuperar cadenas de conexión de archivos de configuración.
<connectionStrings>
<add name="DatabaseConnection"
connectionString="Data Source=(local);Initial
Catalog=Northwind;Integrated Security=true;" />
</connectionStrings>
Sintaxis de KeyRestrictions
En el ejemplo siguiente se habilita la Encrypt misma Packet Size cadena de conexión, se habilita el uso de las
opciones de cadena de conexión y, pero se restringe el uso de cualquier otra opción de cadena de conexión.
<connectionStrings>
<add name="DatabaseConnection"
connectionString="Data Source=(local);Initial
Catalog=Northwind;Integrated Security=true;"
KeyRestrictions="Encrypt=;Packet Size=;"
KeyRestrictionBehavior="AllowOnly" />
</connectionStrings>
<connectionStrings>
<add name="DatabaseConnection"
connectionString="Data Source=(local);Initial
Catalog=Northwind;Integrated Security=true;"
KeyRestrictions="User Id=;Password=;Persist Security Info=;"
KeyRestrictionBehavior="PreventUsage" />
</connectionStrings>
<add name="DatabaseConnection2"
connectionString="Data Source=SqlServer2;Initial
Catalog=Northwind2;Integrated Security=true;"
KeyRestrictions="Initial Catalog;Connection Timeout=;
Encrypt=;Packet Size=;"
KeyRestrictionBehavior="AllowOnly" />
</connectionStrings>
<PermissionSet class="System.Security.NamedPermissionSet"
version="1"
Name="CustomLocalIntranet"
Description="Custom permission set given to applications on
the local intranet">
IMPORTANT
Al diseñar permisos de seguridad CAS en ADO.NET, el procedimiento correcto es comenzar con el caso más restrictivo (sin
ningún permiso) y agregar a continuación los permisos específicos necesarios para la tarea determinada que el código debe
realizar. El patrón opuesto, que comienza con todos los permisos y deniega a continuación un permiso concreto, no es
seguro puesto que existen muchas formas de expresar la misma cadena de conexión. Por ejemplo, si comienza con todos los
permisos y después intenta denegar el uso de la cadena de conexión "servidor=unServidor", la cadena
"servidor=unServidor.miEmpresa.com" seguirá obteniendo permiso. Al comenzar siempre por no conceder ningún permiso,
se reduce la posibilidad de que haya lagunas en el conjunto de permisos.
En el siguiente código se muestra cómo SqlClient realiza la petición de seguridad, que inicia SecurityException si
los permisos de seguridad CAS adecuados no se encuentran en su lugar. El resultado SecurityException se muestra
en la ventana de la consola.
using System;
using System.Data;
using System.Data.SqlClient;
using System.Security;
using System.Security.Permissions;
namespace PartialTrustTopic {
public class PartialTrustHelper : MarshalByRefObject {
public void TestConnectionOpen(string connectionString) {
// Try to open a connection.
using (SqlConnection connection = new SqlConnection(connectionString)) {
connection.Open();
}
}
}
class Program {
static void Main(string[] args) {
TestCAS("Data Source=(local);Integrated Security=true", "Data Source=(local);Integrated
Security=true;Initial Catalog=Test");
}
// Create sandbox AppDomain with permission set that only allows execution,
// and has no SqlClientPermissions.
AppDomainSetup appDomainSetup = new AppDomainSetup();
appDomainSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
AppDomain firstDomain = AppDomain.CreateDomain("NoSqlPermissions", null, appDomainSetup,
permissions);
// Create helper object in sandbox AppDomain so that code can be executed in that AppDomain.
Type helperType = typeof(PartialTrustHelper);
PartialTrustHelper firstHelper =
(PartialTrustHelper)firstDomain.CreateInstanceAndUnwrap(helperType.Assembly.FullName, helperType.FullName);
try {
// Attempt to open a connection in the sandbox AppDomain.
// This is expected to fail.
firstHelper.TestConnectionOpen(connectString1);
firstHelper.TestConnectionOpen(connectString1);
Console.WriteLine("Connection opened, unexpected.");
}
catch (System.Security.SecurityException ex) {
Console.WriteLine("Failed, as expected: {0}",
ex.FirstPermissionThatFailed);
permissions.AddPermission(sqlPermission);
Imports System.Data
Imports System.Data.SqlClient
Imports System.Security
Imports System.Security.Permissions
Namespace PartialTrustTopic
Public Class PartialTrustHelper
Inherits MarshalByRefObject
Public Sub TestConnectionOpen(ByVal connectionString As String)
' Try to open a connection.
Using connection As New SqlConnection(connectionString)
connection.Open()
End Using
End Sub
End Class
Class Program
Public Shared Sub Main(ByVal args As String())
TestCAS("Data Source=(local);Integrated Security=true", "Data Source=(local);Integrated
Security=true;Initial Catalog=Test")
End Sub
' Create sandbox AppDomain with permission set that only allows execution,
' and has no SqlClientPermissions.
Dim appDomainSetup As New AppDomainSetup()
appDomainSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase
Dim firstDomain As AppDomain = AppDomain.CreateDomain("NoSqlPermissions", Nothing, appDomainSetup,
permissions)
' Create helper object in sandbox AppDomain so that code can be executed in that AppDomain.
Dim helperType As Type = GetType(PartialTrustHelper)
Dim firstHelper As PartialTrustHelper =
DirectCast(firstDomain.CreateInstanceAndUnwrap(helperType.Assembly.FullName, helperType.FullName),
PartialTrustHelper)
Try
' Attempt to open a connection in the sandbox AppDomain.
' This is expected to fail.
firstHelper.TestConnectionOpen(connectString1)
Console.WriteLine("Connection opened, unexpected.")
Catch ex As System.Security.SecurityException
permissions.AddPermission(sqlPermission)
Consulte también
Proteger aplicaciones de ADO.NET
Seguridad del código nativo y del código de .NET Framework
Seguridad basada en roles
Información general de ADO.NET
Privacidad y seguridad de datos
08/01/2020 • 5 minutes to read • Edit Online
.NET Framework se basa en el sistema de tipos común, que define cómo se declaran, usan y administran los tipos
en tiempo de ejecución. Consta de tipos de valor y de tipos de referencia, que derivan todos del tipo base Object.
Al trabajar con un origen de datos, el tipo de datos se deduce del proveedor de datos si no se especifica
explícitamente. Por ejemplo, un objeto DataSet es independiente de cualquier origen de datos específico. Los
datos de DataSet se recuperan desde un origen de datos y los cambios que se realizan en ellos se reflejan en el
origen de datos mediante el uso de DataAdapter . Esto significa que cuando un DataAdapter rellena un DataTable
en un DataSet con valores de un origen de datos, los tipos de datos resultantes de las columnas del DataTable
son .NET Framework tipos, en lugar de tipos específicos del proveedor de datos .NET Framework que se utiliza
para conectarse al origen de datos.
Del mismo modo, cuando un DataReader devuelve un valor de un origen de datos, el valor resultante se
almacena en una variable local que tiene un tipo .NET Framework. En el caso de las operaciones Fill del
DataAdapter y de los métodos Get del DataReader , el tipo de .NET Framework se deduce del valor devuelto del
proveedor de datos .NET Framework.
En lugar de confiar en el tipo de datos deducido, puede utilizar los métodos de descriptor de acceso con tipo de
DataReader cuando conoce el tipo específico del valor que se va a devolver. Los métodos de descriptor de acceso
con tipo proporcionan un mejor rendimiento al devolver un valor como un tipo de .NET Framework específico, lo
que elimina la necesidad de conversión de tipos adicional.
NOTE
Los valores NULL de los tipos de datos del proveedor de datos de .NET Framework se representan mediante
DBNull.Value .
Esta sección
Asignaciones de tipos de datos de SQL Server
Enumera las asignaciones de tipos de datos deducidas y los métodos de descriptor de acceso a datos de
System.Data.SqlClient.
Asignaciones de tipos de datos de OLE DB
Enumera las asignaciones de tipos de datos deducidas y los métodos de descriptor de acceso a datos de
System.Data.OleDb.
Asignaciones de tipos de datos de ODBC
Enumera las asignaciones de tipos de datos deducidas y los métodos de descriptor de acceso a datos de
System.Data.Odbc.
Asignaciones de tipos de datos de Oracle
Enumera las asignaciones de tipos de datos deducidas y los métodos de descriptor de acceso a datos de
System.Data.OracleClient.
Números de punto flotante
Describe los problemas que con frecuencia se encuentran los programadores al trabajar con números de punto
flotante.
Vea también
Tipos de datos de SQL Server y ADO.NET
Configuración de parámetros y tipos de datos de parámetros
Recuperación de información del esquema de la base de datos
Sistema de tipos comunes
Convertir tipos
Información general sobre ADO.NET
Asignaciones de tipos de datos de SQL Server
23/10/2019 • 3 minutes to read • Edit Online
SQL Server y .NET Framework se basan en sistemas de tipos distintos. Por ejemplo, la estructura Decimal de .NET
Framework tiene una escala máxima de 28, mientras que los tipos de datos decimal y numérico de SQL Server
tienen una escala máxima de 38. Para mantener la integridad de los datos al leer y escribir datos, SqlDataReader
expone métodos de descriptores de acceso con tipo específicos de SQL Server que devuelven objetos de
System.Data.SqlTypes así como métodos de descriptores de acceso que devuelven tipos de .NET Framework. Los
tipos de SQL Server y los de .NET Framework se representan también mediante enumeraciones en las clases
DbType y SqlDbType, que puede usar al especificar los tipos de datos SqlParameter.
En la tabla siguiente se muestra el tipo de .NET Framework deducido DbType , SqlDbType las enumeraciones y y
SqlDataReaderlos métodos de descriptor de acceso para.
Char[] GetChars
Char[] GetChars
Char[] GetChars
Char[] GetChars
Char[] GetChars
Vea también
Tipos de datos de SQL Server y ADO.NET
Datos binarios y datos de valores grandes de SQL Server
Asignaciones de tipos de datos en ADO.NET
Configuración de parámetros y tipos de datos de parámetros
Información general sobre ADO.NET
Asignaciones de tipos de datos de OLE DB
23/10/2019 • 2 minutes to read • Edit Online
En la tabla siguiente se muestra el tipo de .NET Framework deducido para los tipos de datos del proveedor de
datos .NET Framework paraSystem.Data.OleDbADO y OLE DB (). También OleDbDataReader se enumeran los
métodos de descriptor de acceso con tipo para.
. N ET F RA M EW O RK
DESC RIP TO R DE A C C ESO
T IP O DE A DO T IP O DE O L E DB T IP O . N ET F RA M EW O RK C O N T IP O
*En el caso de DBTYPE_IUNKNOWN los DBTYPE_IDISPATCH tipos de OLE DB y, la referencia de objeto es una
representación de cálculo de referencias del puntero.
Vea también
Recuperar y modificar datos en ADO.NET
Información general sobre ADO.NET
Asignaciones de tipos de datos de ODBC
23/10/2019 • 2 minutes to read • Edit Online
En la tabla siguiente se muestra el tipo de .NET Framework deducido para los tipos de datos del proveedor de
datosSystem.Data.Odbcde .NET Framework para ODBC (). También OdbcDataReader se enumeran los métodos de
descriptor de acceso con tipo para.
. N ET F RA M EW O RK DESC RIP TO R DE
T IP O DE O DB C T IP O . N ET F RA M EW O RK A C C ESO C O N T IP O
Char[] GetChars()
Char[] GetChars()
Char[] GetChars()
Char[] GetChars()
Char[] GetChars()
Vea también
Recuperar y modificar datos en ADO.NET
Información general sobre ADO.NET
Asignaciones de tipos de datos de Oracle
23/10/2019 • 6 minutes to read • Edit Online
En la siguiente tabla se enumeran los tipos de datos de Oracle y sus asignaciones al OracleDataReader.
T IP O DE DATO S
T IP O DE DATO S DE . N ET O RA C L EC L IEN T DEVUELTO
F RA M EW O RK DEVUELTO P O R POR
O RA C L EDATA REA DER. GET VA O RA C L EDATA REA DER. GETO R
T IP O DE DATO S DE O RA C L E L UE A C L EVA L UE C O M EN TA RIO S
En la tabla siguiente se enumeran los tipos de datos de Oracle y los tipos de datos .NET Framework
OracleType(System. Data. DbType y) que se van a usar al enlazarlos como parámetros.
EN UM ERA C IÓ N
EN UM ERA C IÓ N DBT Y P E O RA C L ET Y P E PA RA
PA RA EN L A Z A R C O M O UN EN L A Z A R C O M O UN
T IP O DE DATO S DE O RA C L E PA RÁ M ET RO PA RÁ M ET RO C O M EN TA RIO S
EN UM ERA C IÓ N
EN UM ERA C IÓ N DBT Y P E O RA C L ET Y P E PA RA
PA RA EN L A Z A R C O M O UN EN L A Z A R C O M O UN
T IP O DE DATO S DE O RA C L E PA RÁ M ET RO PA RÁ M ET RO C O M EN TA RIO S
FLOAT Single, Double, decimal Float, Double, número Sizedetermina los datos
System. Data. DBType y
OracleType.
INTEGER SByte, Int16, Int32, SByte, Int16, Int32, Sizedetermina los datos
Int64, Decimal Number System. Data. DBType y
OracleType.
ENTERO SIN SIGNO Byte, UInt16, UInt32, Byte, UInt16, Uint32, Sizedetermina los datos
UInt64, Decimal número System. Data. DBType y
OracleType.
Vea también
Oracle y ADO.NET
Información general sobre ADO.NET
Números de punto flotante
23/10/2019 • 3 minutes to read • Edit Online
En este tema se describen algunos de los problemas que los desarrolladores suelen encontrar al trabajar con
números de punto flotante en ADO.NET. Estos problemas se deben a la manera en que los equipos almacenan
números de punto flotante y no son específicos de un proveedor determinado System.Data.SqlClient como
System.Data.OracleCliento.
En general, los números de punto flotante no tienen una representación binaria exacta. En realidad, el equipo
almacena una aproximación del número. En diferentes momentos se pueden utilizar diferentes números de dígitos
binarios para representar el número. Cuando un número de punto flotante se convierte de una representación a
otra, los dígitos menos significativos de dicho número pueden variar ligeramente. Por lo general el cambio se
produce cuando el número se convierte de un tipo a otro. La variación se produce si la conversión se realiza en una
base de datos, entre tipos que representan valores de base de datos o entre tipos. Debido a estos cambios, los
números que lógicamente deberían ser iguales pueden presentar cambios en sus dígitos menos significativos que
hagan que muestren valores diferentes. La cantidad de dígitos de precisión en el número puede ser mayor o
menor de la esperada. Cuando el formato del número cambia a cadena, puede que no muestre el valor esperado.
Para reducir estos efectos al mínimo, debe usar la coincidencia más próxima entre tipos de números que haya
disponible. Por ejemplo, si está trabajando con SQL Server, el valor numérico exacto puede cambiar si convierte un
valor de Transact-SQL de tipo real en un valor de tipo float. En el .NET Framework, la conversión Single de Double a
también puede producir resultados inesperados. En ambos casos, una estrategia adecuada consiste en establecer
que todos los valores de la aplicación usen el mismo tipo numérico. También puede utilizar un tipo de decimal de
precisión fija o bien convertir los números de punto flotante a un tipo decimal de precisión fija antes de trabajar
con ellos.
Para solucionar problemas relacionados con la comparación de igualdad, puede codificar la aplicación de forma
que se pasen por alto las diferentes en los dígitos menos significativos. Por ejemplo, en lugar de comparar dos
números para comprobar si son iguales, puede restar un número del otro. Si la diferencia se sitúa en un margen
aceptable de redondeo, la aplicación puede considerar los números como si fuesen iguales.
Vea también
Por qué los números de punto flotante pierden precisión
Información general sobre ADO.NET
Recuperar y modificar datos en ADO.NET
05/02/2020 • 4 minutes to read • Edit Online
La principal función de cualquier aplicación de base de datos es conectarse a un origen de datos y recuperar los
datos que contiene. Los .NET Framework proveedores de datos de ADO.NET sirven como puente entre una
aplicación y un origen de datos, lo que le permite ejecutar comandos, así como recuperar datos mediante un
DataReader o un DataAdapter . Una función clave de cualquier aplicación de base de datos es la capacidad de
actualizar los datos almacenados en la misma. En ADO.NET, la actualización de datos implica el uso de los
objetos DataAdapter y DataSet, y de los objetos de comando . también puede implicar el uso de
transacciones.
Esta sección
Conexión a un origen de datos
Describe cómo se establece una conexión con un origen de datos y cómo trabajar con eventos de conexión.
Cadenas de conexión
Contiene temas en los que se describen varios aspectos del uso de cadenas de conexión, entre los que se
incluyen las palabras clave de cadena de conexión, información sobre seguridad y el almacenamiento y
recuperación de cadenas de conexión.
Agrupación de conexiones
Describe la agrupación de conexiones para los proveedores de datos .NET Framework.
Comandos y parámetros
Contiene temas en los que se describe cómo crear comandos y generadores de comandos, configurar
parámetros y cómo ejecutar comandos para recuperar y modificar datos.
Objetos DataAdapter y DataReader
Contiene temas en los que se describen DataReaders, DataAdapters, los parámetros, el control de eventos
DataAdapter y la ejecución de operaciones por lotes.
Transacciones y simultaneidad
Contiene temas en los que se describe cómo realizar transacciones locales y transacciones distribuidas, y cómo
trabajar con la simultaneidad optimista.
Recuperación de valores autonuméricos y de identidad
Proporciona un ejemplo de asignación de los valores generados para una columna de identidad en una tabla
de SQL Server o para un campo Autonumber de una tabla de Microsoft Access, a una columna de una fila
insertada en una tabla. Describe la combinación de valores de identidad en una DataTable .
Recuperación de datos binarios
Describe cómo recuperar datos binarios o estructuras de datos de gran tamaño mediante CommandBehavior .
SequentialAccess para modificar el comportamiento predeterminado de un DataReader .
Vea también
Asignaciones de tipos de datos en ADO.NET
Objetos DataSet, DataTable y DataView
Proteger aplicaciones de ADO.NET
SQL Server y ADO.NET
Información general sobre ADO.NET
Conectarse a un origen de datos en ADO.NET
10/02/2020 • 2 minutes to read • Edit Online
En ADO.NET, se usa un objeto de conexión para conectarse a un origen de datos específico proporcionando la
información de autenticación necesaria en una cadena de conexión. El objeto de conexión que se utiliza depende
del tipo de origen de datos.
Cada proveedor de datos .NET Framework incluye un objeto DbConnection: el proveedor de datos .NET
Framework para OLE DB incluye un objeto OleDbConnection, el proveedor de datos .NET Framework para SQL
Server incluye un objeto SqlConnection, el proveedor de datos .NET Framework para ODBC incluye un objeto
OdbcConnection y el proveedor de datos .NET Framework para Oracle incluye un objeto OracleConnection.
En esta sección
Establecimiento de la conexión
Describe cómo utilizar un objeto de conexión para establecer una conexión a un origen de datos.
Eventos de conexión
Describe cómo usar un evento InfoMessage para recuperar mensajes informativos de un origen de datos.
Consulte también
Cadenas de conexión
Agrupación de conexiones
Comandos y parámetros
Objetos DataAdapter y DataReader
Transacciones y simultaneidad
Información general sobre ADO.NET
Establecer la conexión
21/03/2020 • 10 minutes to read • Edit Online
Para conectarse a Microsoft SQL Server, use el objeto SqlConnection del proveedor de datos .NET Framework para
SQL Server. Para conectarse a un origen de datos OLE DB, use el objeto OleDbConnection del proveedor de datos
.NET Framework para OLE DB. Para conectarse a un origen de datos ODBC, utilice el objeto OdbcConnection del
proveedor de datos .NET Framework para ODBC. Para conectarse a un origen de datos Oracle, utilice el objeto
OracleConnection del proveedor de datos .NET Framework para ODBC. Para almacenar y recuperar cadenas de
conexión de forma segura, consulte Protección dela información de conexión .
Cierre de conexiones
Recomendamos cerrar siempre la conexión cuando termine de utilizarla, para que la conexión pueda regresar al
grupo. El bloque Using de Visual Basic o C# elimina automáticamente la conexión cuando el código sale del
bloque, incluso en el caso de una excepción no controlada. Consulte Using Statement y Using Statement para
obtener más información.
También puede utilizar los métodos Close o Dispose del objeto de conexión correspondiente al proveedor que
esté utilizando. Es posible que las conexiones que no se cierran explícitamente no se puedan agregar ni puedan
regresar al grupo. Por ejemplo, una conexión que se ha salido del ámbito pero que no se ha cerrado explícitamente
solo se devolverá al grupo de conexión si se ha alcanzado el tamaño máximo del grupo y la conexión aún es válida.
Para obtener más información, vea Agrupación de conexiones OLE DB, ODBC y Oracle.
NOTE
No llame Close Dispose ni en un Connection , un DataReader Finalize o cualquier otro objeto administrado en el
método de la clase. En un finalizador, libere solo los recursos no administrados que pertenezcan directamente a su clase. Si la
clase no dispone de recursos no administrados, no incluya un método Finalize en la definición de clase. Para obtener más
información, consulte Recolección de elementos no utilizados.
NOTE
Los eventos de inicio y cierre de sesión no se provocarán en el servidor cuando se busque una conexión desde el grupo de
conexiones o se devuelva a éste, puesto que la conexión no está cerrada realmente cuando se devuelve al grupo de
conexiones. Para más información, consulte el artículo sobre la agrupación de conexiones de SQL Server (ADO.NET).
NOTE
El objeto OleDbConnection no admite la configuración ni la recuperación de propiedades dinámicas específicas de un
proveedor OLE DB. Solo se admiten las propiedades que se pueden proporcionar en la cadena de conexión para el proveedor
OLE DB.
El siguiente código de ejemplo demuestra cómo crear y abrir una conexión a un origen de datos OLE DB.
Consulte también
Conectarse a un origen de datos
Cadenas de conexión
Agrupación de conexiones de OLE DB, ODBC y Oracle
Información general de ADO.NET
Eventos de Connection
21/03/2020 • 6 minutes to read • Edit Online
Todos los proveedores de datos de .NET Framework tienen objetos Connection con dos eventos que puede usar
para recuperar mensajes informativos de un origen de datos o para determinar si ha cambiado el estado de una
conexión. En la tabla siguiente se describen los eventos del objeto Connection.
NOTE
Los errores con un nivel de gravedad de 17, como mínimo, que hacen que el servidor interrumpa el procesamiento de
comandos, deben controlarse como excepciones. En este caso, se inicia una excepción, independientemente del modo en que
se controle el error en el evento InfoMessage.
Console.WriteLine( _
"The current Connection state has changed from {0} to {1}.", _
args.OriginalState, args.CurrentState)
End Sub
Consulte también
Conectarse a un origen de datos
Información general de ADO.NET
Cadenas de conexión de ADO.NET
05/02/2020 • 5 minutes to read • Edit Online
Una cadena de conexión contiene información de inicialización que se transfiere como un parámetro desde un
proveedor de datos a un origen de datos. El proveedor de datos recibe la cadena de conexión como el valor de la
propiedad DbConnection.ConnectionString. El proveedor analiza la cadena de conexión y garantiza que la sintaxis
es correcta y que se admiten las palabras clave. A continuación, el método DbConnection.Open() pasa los
parámetros de conexión analizados al origen de datos. El origen de datos realiza una validación adicional y
establece una conexión.
keyword1=value; keyword2=value;
Las palabras clave no distinguen mayúsculas de minúsculas. Sin embargo, los valores pueden distinguir entre
mayúsculas y minúsculas, en función del origen de datos. Las palabras clave y los valores pueden contener
caracteres de espacio en blanco. Los espacios en blanco iniciales y finales se omiten en las palabras clave y los
valores sin comillas.
Si un valor contiene el punto y coma, caracteres de control Unicodeo espacios en blanco iniciales o finales, debe
incluirse entre comillas simples o dobles. Por ejemplo:
Es posible que el carácter envolvente no se encuentre dentro del valor que contiene. Por lo tanto, un valor que
contenga comillas simples solo se puede incluir entre comillas dobles y viceversa:
Keyword='double"quotation;mark';
Keyword="single'quotation;mark";
Keyword="double""quotation";
Keyword='single''quotation';
Las comillas, así como el signo igual, no requieren caracteres de escape, por lo que las siguientes cadenas de
conexión son válidas:
Puesto que cada valor se lee hasta el punto y coma siguiente o el final de la cadena, el valor del último ejemplo es
a=b=c y el punto y coma final es opcional.
Todas las cadenas de conexión comparten la misma sintaxis básica que se ha descrito anteriormente. Sin
embargo, el conjunto de palabras clave reconocidas depende del proveedor y ha evolucionado a lo largo de los
años desde API anteriores, como ODBC. El proveedor de datos de .NET Framework para SQL Server ( SqlClient )
admite muchas palabras clave de API anteriores, pero suele ser más flexible y acepta sinónimos para muchas de
las palabras clave de cadena de conexión comunes.
Los errores tipográficos pueden producir errores. Por ejemplo, Integrated Security=true es válido, pero
IntegratedSecurity=true produce un error.
Las cadenas de conexión construidas manualmente en tiempo de ejecución desde la entrada de usuario no
validada son vulnerables a ataques de inyección de cadenas y ponen en peligro la seguridad en el origen de
datos. Para solucionar estos problemas, ADO.NET 2,0 presentó generadores de cadenas de conexión para cada
proveedor de datos .NET Framework . Estos generadores de cadenas de conexión exponen parámetros como
propiedades fuertemente tipadas y permiten validar la cadena de conexión antes de enviarla al origen de datos.
Esta sección
Generadores de cadenas de conexión
Muestra cómo usar las clases ConnectionStringBuilder para construir cadenas de conexión válidas en tiempo de
ejecución.
Cadenas de conexión y archivos de configuración
Muestra cómo almacenar y recuperar cadenas de conexión en archivos de configuración.
\ de Sintaxis de cadena de conexión
Proteger la información de conexión
Muestra técnicas de protección de la información utilizada para conectarse a un origen de datos.
Vea también
Conexión a un origen de datos
Información general sobre ADO.NET
Generadores de cadenas de conexión
21/03/2020 • 7 minutes to read • Edit Online
System.Data.SqlClient System.Data.SqlClient.SqlConnectionStringBuilder
System.Data.OleDb System.Data.OleDb.OleDbConnectionStringBuilder
System.Data.Odbc System.Data.Odbc.OdbcConnectionStringBuilder
System.Data.OracleClient System.Data.OracleClient.OracleConnectionStringBuilder
El resultado muestra que SqlConnectionStringBuilder controla esta situación correctamente, ya que establece el
escape del valor adicional entre comillas dobles en lugar de anexarlo a la cadena de conexión como un nuevo
par clave-valor.
NOTE
El espacio de nombres System.Configuration permite el acceso mediante programación a archivos de configuración que
usan WebConfigurationManager en aplicaciones web y ConfigurationManager en aplicaciones Windows. Para obtener
más información sobre cómo trabajar con cadenas de conexión y archivos de configuración, vea Cadenas de conexión y
archivosde configuración .
Ejemplo
En este ejemplo se muestra la recuperación de una cadena de conexión incluida en un archivo de configuración
y cómo se completa mediante el establecimiento de las propiedades DataSource, UserID y Password de
SqlConnectionStringBuilder. El archivo de configuración se define de la siguiente forma.
<connectionStrings>
<clear/>
<add name="partialConnectString"
connectionString="Initial Catalog=Northwind;"
providerName="System.Data.SqlClient" />
</connectionStrings>
NOTE
Para ejecutar el código, debe establecer una referencia al archivo System.Configuration.dll del proyecto.
private static void BuildConnectionString(string dataSource,
string userName, string userPassword)
{
// Retrieve the partial connection string named databaseConnection
// from the application's app.config or web.config file.
ConnectionStringSettings settings =
ConfigurationManager.ConnectionStrings["partialConnectString"];
if (null != settings)
{
// Retrieve the partial connection string.
string connectString = settings.ConnectionString;
Console.WriteLine("Original: {0}", connectString);
Consulte también
Cadenas de conexión
Privacidad y seguridad de datos
Información general de ADO.NET
Cadenas de conexión y archivos de configuración
27/03/2020 • 22 minutes to read • Edit Online
NOTE
Puede guardar parte de la cadena de conexión en un archivo de configuración y usar la clase DbConnectionStringBuilder
para completarla en tiempo de ejecución. Esto resulta útil en escenarios en los que no se conocen los elementos de la
cadena de conexión por anticipado o cuando no desea guardar información confidencial en un archivo de configuración.
Para obtener más información, vea Generadores de cadenas de conexión.
<connectionStrings>
<add name="Name"
providerName="System.Data.ProviderName"
connectionString="Valid Connection String;" />
</connectionStrings>
En el archivo de configuración principal de la aplicación, use el atributo configSource para especificar el nombre
completo y la ubicación del archivo externo. En este ejemplo se hace referencia a un archivo de configuración
externo denominado connections.config .
NOTE
El archivo machine.config también contiene una sección connectionStrings , donde se encuentran las cadenas de
conexión que usa Visual Studio. Al recuperar cadenas de conexión por nombre de proveedor desde el archivo app.config
en una aplicación de Windows, las cadenas de conexión de machine.config se cargan primero y, a continuación, las
entradas de app.config . Agregar clear inmediatamente después de la connectionStrings elemento quita todas las
referencias heredadas de la estructura de datos en memoria, de modo que sólo se tienen en cuenta las cadenas de conexión
definidas en el archivo app.config local.
NOTE
El acceso a los archivos de configuración en tiempo de ejecución requiere la concesión de permisos al llamador; los permisos
necesarios dependen del tipo de aplicación, del archivo de configuración y de la ubicación. Para obtener más información,
vea Utilizar las clases Configuration y WebConfigurationManager para las aplicaciones ASP.NET, o bien
ConfigurationManager para las aplicaciones Windows.
Puede usar ConnectionStringSettingsCollection para recuperar cadenas de conexión de archivos de configuración
de aplicación. Esta clase contiene una colección de objetos ConnectionStringSettings, cada uno de los cuales
representa una única entrada en la sección connectionStrings . Sus propiedades se asignan a los atributos de
cadenas de conexión, lo que permite recuperar una cadena de conexión mediante la especificación de su nombre
o del nombre del proveedor.
NOTE
System.Configuration.dll no se incluye en todos los tipos de proyectos y es posible que deba establecer una referencia a
este elemento para usar las clases de configuración. El nombre y la ubicación de un archivo de configuración de aplicación
determinado varían en función del tipo de aplicación y del proceso de hospedaje.
using System.Configuration;
class Program
{
static void Main()
{
GetConnectionStrings();
Console.ReadLine();
}
if (settings != null)
{
foreach(ConnectionStringSettings cs in settings)
{
Console.WriteLine(cs.Name);
Console.WriteLine(cs.ProviderName);
Console.WriteLine(cs.ConnectionString);
}
}
}
}
Imports System.Configuration
Class Program
Shared Sub Main()
GetConnectionStrings()
Console.ReadLine()
End Sub
return returnValue;
}
' Retrieves a connection string by name.
' Returns Nothing if the name is not found.
Private Shared Function GetConnectionStringByName( _
ByVal name As String) As String
Return returnValue
End Function
Return returnValue
End Function
<connectionStrings configProtectionProvider="DataProtectionConfigurationProvider">
<EncryptedData>
<CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAH2... </CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
Cuando se recupera la cadena de conexión cifrada en tiempo de ejecución, .NET Framework usa el proveedor
especificado para descifrar CipherValue y que así esté disponible para la aplicación. No es necesario escribir
ningún código adicional para administrar el proceso de descifrado.
Proveedores de configuración protegida
Los proveedores de configuración protegida se registran en la sección configProtectedData del archivo
machine.config en el equipo local, como se muestra en el fragmento siguiente, donde se pueden ver los dos
proveedores de configuración protegida que proporciona .NET Framework. Los valores que se muestran se han
truncado para facilitar la lectura.
<configProtectedData defaultProvider="RsaProtectedConfigurationProvider">
<providers>
<add name="RsaProtectedConfigurationProvider"
type="System.Configuration.RsaProtectedConfigurationProvider" />
<add name="DataProtectionConfigurationProvider"
type="System.Configuration.DpapiProtectedConfigurationProvider" />
</providers>
</configProtectedData>
Puede configurar otros proveedores de configuración protegida si los agrega al archivo machine.config .
Asimismo, puede crear su propio proveedor de configuración protegida heredando de la clase base abstracta
ProtectedConfigurationProvider. En la tabla siguiente se describen los dos archivos de configuración incluidos en
.NET Framework.
Ambos proveedores proporcionan cifrado de datos de alta seguridad. No obstante, si prevé usar el mismo archivo
de configuración de cifrado en varios servidores como, por ejemplo, una granja de servidores web, solo
RsaProtectedConfigurationProvider permite exportar las claves de cifrado usadas para cifrar los datos e
importarlas a otro servidor. Para obtener más información, vea Importar y exportar contenedores de claves RSA
con configuración protegida.
Uso de clases de configuración
El espacio de nombres System.Configuration proporciona clases para trabajar con valores de configuración
mediante programación. La clase ConfigurationManager proporciona acceso a los archivos de configuración de
equipo, aplicación y usuario. Si va a crear una aplicación WebConfigurationManager ASP.NET, puede utilizar la
clase, que proporciona la misma funcionalidad y, al mismo tiempo, le permite acceder a la configuración que es
exclusiva de ASP.NET aplicaciones, como las que se encuentran en ** <system.web>**.
NOTE
El espacio de nombres System.Security.Cryptography contiene clases que proporcionan opciones adicionales para cifrar y
descifrar datos. Use estas clases si requiere servicios criptográficos que no están disponibles cuando se usa la configuración
protegida. Algunas de estas clases son contenedores de Microsoft CryptoAPI no administrado, mientras que otras son
simplemente implementaciones administradas. Para más información, vea Servicios criptográficos.
Ejemplo de App.config
En este ejemplo se muestra cómo alternar el cifrado de la sección connectionStrings de un archivo app.config
para una aplicación Windows. En este ejemplo, el procedimiento recibe el nombre de la aplicación como
argumento, por ejemplo, "MyApplication.exe". Después, el archivo app.config se cifra y se copia en la carpeta que
contiene el ejecutable con el nombre "MyApplication.exe.config".
NOTE
La cadena de conexión solo se puede descifrar en el equipo donde se ha cifrado.
El código usa el método OpenExeConfiguration para abrir el archivo app.config y editarlo; el método GetSection
devuelve la sección connectionStrings . A continuación, el código comprueba la propiedad IsProtected y llama a
ProtectSection para cifrar la sección si no está cifrada. Para descifrar la sección se llama al método
UnprotectSection. El método Save completa la operación y guarda los cambios.
NOTE
Para ejecutar el código, debe establecer una referencia al archivo System.Configuration.dll del proyecto.
static void ToggleConfigEncryption(string exeConfigName)
{
// Takes the executable file name without the
// .config extension.
try
{
// Open the configuration file and retrieve
// the connectionStrings section.
Configuration config = ConfigurationManager.
OpenExeConfiguration(exeConfigName);
ConnectionStringsSection section =
config.GetSection("connectionStrings")
as ConnectionStringsSection;
if (section.SectionInformation.IsProtected)
{
// Remove encryption.
section.SectionInformation.UnprotectSection();
}
else
{
// Encrypt the section.
section.SectionInformation.ProtectSection(
"DataProtectionConfigurationProvider");
}
// Save the current configuration.
config.Save();
Console.WriteLine("Protected={0}",
section.SectionInformation.IsProtected);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Shared Sub ToggleConfigEncryption(ByVal exeConfigName As String)
' Takes the executable file name without the
' .config extension.
Try
' Open the configuration file and retrieve
' the connectionStrings section.
Dim config As Configuration = ConfigurationManager. _
OpenExeConfiguration(exeConfigName)
If section.SectionInformation.IsProtected Then
' Remove encryption.
section.SectionInformation.UnprotectSection()
Else
' Encrypt the section.
section.SectionInformation.ProtectSection( _
"DataProtectionConfigurationProvider")
End If
Console.WriteLine("Protected={0}", _
section.SectionInformation.IsProtected)
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Sub
Ejemplo de Web.config
Este ejemplo usa el método OpenWebConfiguration de WebConfigurationManager . Observe que en este caso
puede indicar la ruta de acceso relativa al archivo Web.config mediante una tilde. El código requiere una
referencia a la clase System.Web.Configuration .
// Toggle encryption.
if (section.SectionInformation.IsProtected)
{
section.SectionInformation.UnprotectSection();
}
else
{
section.SectionInformation.ProtectSection(
"DataProtectionConfigurationProvider");
}
Para obtener más información acerca de cómo proteger ASP.NET aplicaciones, consulte Protección de sitios web
de ASP.NET.
Vea también
Generadores de cadenas de conexión
Proteger la información de conexión
Utilizar las clases Configuration
Configurar aplicaciones
Administrar sitios web ASP.NET
Información general sobre ADO.NET
Sintaxis de cadenas de conexión
21/03/2020 • 17 minutes to read • Edit Online
Cada proveedor de datos .NET Framework tiene un objeto Connection que hereda de la clase DbConnection, así
como una propiedad ConnectionString específica del proveedor. La sintaxis de la cadena de conexión específica de
cada proveedor se indica en su propiedad ConnectionString . En la tabla siguiente se muestran los cuatro
proveedores de datos que se incluyen en .NET Framework.
P RO VEEDO R DE DATO S DE . N ET F RA M EW O RK ( . N ET
F RA M EW O RK DATA P RO VIDER) DESC RIP C IÓ N
Autenticación de Windows
Se recomienda usar la autenticación de Windows (a veces denominada seguridad integrada) para conectarse a
orígenes de datos que lo admiten. La sintaxis utilizada en la cadena de conexión varía dependiendo del proveedor.
En la siguiente tabla se muestra la sintaxis de autenticación de Windows utilizada con los proveedores de datos
.NET Framework.
P RO VEEDO R SIN TA XIS
-- or --
Integrated Security=SSPI;
Odbc Trusted_Connection=yes;
NOTE
Integrated Security=true produce una excepción cuando se usa con el proveedor OleDb .
IMPORTANT
La configuración predeterminada Persist Security Info de false la palabra clave es . Si se establece en true o yes ,
permite obtener información de seguridad confidencial de la conexión, incluidos el identificador de usuario y la contraseña,
una vez abierta la conexión. Manténgase Persist Security Info false establecido para asegurarse de que un origen
que no es de confianza no tiene acceso a la información de cadena de conexión confidencial.
NOTE
La autenticación de Windows tiene prioridad sobre los inicios de sesión de SQL Server. Si especifica Integrated Security=true
junto con un nombre de usuario y una contraseña, se ignorarán el nombre de usuario y la contraseña, y se usará la
autenticación de Windows.
"Data Source=MySqlServer\MSSQL1;"
A la hora de crear una cadena de conexión, también puede establecer la propiedad DataSource del
SqlConnectionStringBuilder en el nombre de instancia. La propiedad DataSource de un objeto SqlConnection es
de solo lectura.
Cambios en Type System Version
La Type System Version palabra SqlConnection.ConnectionString clave en a especifica la representación del lado
cliente de los tipos de SQL ServerSQL Server . Para obtener más información sobre la palabra clave
SqlConnection.ConnectionString, vea Type System Version .
Usar TrustServerCertificate
La TrustServerCertificate palabra clave solo es válida cuando se conecta a una instancia de SQL ServerSQL
Server con un certificado válido. Cuando TrustServerCertificate se establece en true , la capa de transporte
utilizará SSL para cifrar el canal y evitar recorrer la cadena de certificados para validar la confianza.
"TrustServerCertificate=true;"
NOTE
Si TrustServerCertificate se establece en true y se activa el cifrado, se utilizará el nivel de cifrado especificado en el
servidor aunque Encrypt esté establecido en false en la cadena de conexión. De lo contrario, se producirá un error en la
conexión.
Habilitar el cifrado
Para habilitar el cifrado cuando no se ha aprovisionado un certificado en el servidor, las opciones Forzar cifrado
de protocolo y Certificado de servidor de confianza deben establecerse en el Administrador de configuración de
SQL ServerSQL Server . En ese caso, el cifrado utilizará un certificado de servidor autofirmado sin validación si no
se ha proporcionado ningún certificado comprobable en el servidor.
La configuración de las aplicaciones no puede reducir el nivel de seguridad configurado en SQL Server, sino que en
todo caso puede reforzarlo. Una aplicación puede solicitar TrustServerCertificate el Encrypt cifrado true
estableciendo las palabras clave y, garantizando que el cifrado tiene lugar incluso cuando no se ha aprovisionado
un certificado de servidor y no se ha configurado Forzar cifrado de protocolo para el cliente. Sin embargo, si en
la configuración del cliente no está habilitado TrustServerCertificate , seguirá siendo necesario un certificado de
servidor.
En la siguiente tabla se describen todos los casos.
Sí Sí Sí Sí El cifrado se produce
siempre, pero puede
que se utilice un
certificado de servidor
autofirmado.
Si la base de datos Jet está protegida mediante la seguridad de nivel de usuario, debe proporcionar la ubicación
del archivo de información de grupo de trabajo (.mdw). Este archivo se usa para validar las credenciales
presentadas en la cadena de conexión.
IMPORTANT
Es posible proporcionar información de conexión para un OleDbConnection en un archivo de vínculo de datos universal
(UDL); sin embargo, debe evitar hacerlo. Los archivos UDL no están cifrados y exponen la información de cadena de conexión
en texto sin cifrar. Un archivo UDL no se puede proteger mediante .NET Framework, ya que se trata de un recurso basado en
un archivo externo a la aplicación. Los archivos UDL no son compatibles con SqlClient .
"Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=|DataDirectory|\Northwind.mdb;
Jet OLEDB:System Database=|DataDirectory|\System.mdw;"
IMPORTANT
No es necesario especificar la ubicación de la base de datos del sistema en la cadena de conexión si la base de datos
Access/Jet no está protegida. La seguridad está desactivada de forma predeterminada y todos los usuarios se conectan como
el usuario Admin integrado, con una contraseña en blanco. Aun cuando la seguridad a nivel de usuario esté correctamente
implementada, una base de datos Jet sigue siendo vulnerable a los ataques. Por eso no se recomienda almacenar
información delicada en una base de datos Access/Jet a causa de la fragilidad inherente a su esquema de seguridad basado
en archivos.
Conectarse a Excel
Para conectarse a un libro de Excel se utiliza el proveedor Microsoft Jet. En la siguiente cadena de conexión, la
palabra clave Extended Properties establece propiedades que son específicas de Excel. "HDR=Yes;" indica que la
primera fila contiene nombres de columna, no datos, e "IMEX=1;" indica al controlador que siempre lea las
columnas de datos "entremezclados" como texto.
Tenga en cuenta que el carácter de comilla doble necesario en Extended Properties también debe ir incluido entre
comillas dobles.
Sintaxis de cadena de conexión del proveedor de formas de datos
Utilice las palabras clave Provider y Data Provider cuando use el proveedor de formas de datos de Microsoft. En
el siguiente ejemplo se utiliza el proveedor de formas para conectarse a una instancia local de SQL Server.
Para obtener más información acerca de la sintaxis de cadena de conexión ODBC, vea ConnectionString.
Consulte también
Cadenas de conexión
Conectarse a un origen de datos
Información general de ADO.NET
Proteger la información de conexión
21/03/2020 • 7 minutes to read • Edit Online
La protección del acceso al origen de datos es uno de los objetivos más importantes a la hora de proteger una
aplicación. Las cadenas de conexión presentan una posible vulnerabilidad si no se protegen. El almacenamiento
de la información de conexión en texto sin formato o en la memoria ponen en riesgo el sistema completo. Las
cadenas de conexión incrustadas en el código fuente se pueden leer mediante Ildasm.exe (IL Disassembler) para
ver el lenguaje intermedio de Microsoft (MSIL) en un ensamblado compilado.
Pueden surgir vulnerabilidades de seguridad que afecten a las cadenas de conexión en función del tipo de
autenticación usado, de la forma en que las cadenas de conexión se almacenan en memoria y en disco, y de las
técnicas usadas para construirlas en tiempo de ejecución.
<identity impersonate="true"
userName="MyDomain\UserAccount"
password="*****" />
La cuenta de identidad fija debe ser una cuenta con pocos privilegios a la que sólo se le concedan los permisos
necesarios en la base de datos. Además, debe cifrar el archivo de configuración para que el nombre de usuario y
la contraseña no se expongan en texto no cifrado.
Consulte también
Proteger aplicaciones de ADO.NET
Cifrado de la información de configuración mediante la configuración protegida
Seguridad en .NET
Información general de ADO.NET
Agrupación de conexiones
23/10/2019 • 2 minutes to read • Edit Online
La conexión a un origen de datos puede ser un proceso largo. Para minimizar el costo de la apertura de
conexiones, ADO.NET usa una técnica de optimización denominada agrupaciónde conexiones, lo que minimiza el
costo de abrir y cerrar conexiones repetidas veces. Los proveedores de datos .NET Framework tratan de forma
diferente la agrupación de conexiones.
En esta sección
Agrupación de conexiones de SQL Server (ADO.NET)
Proporciona información general sobre la agrupación de conexiones y describe cómo funciona la agrupación de
conexiones en SQL Server.
Agrupación de conexiones de OLE DB, ODBC y Oracle
Describe la agrupación de conexiones en los proveedores de datos .NET Framework para OLE DB, ODBC y Oracle.
Vea también
Recuperar y modificar datos en ADO.NET
Información general sobre ADO.NET
Agrupación de conexiones de SQL Server
(ADO.NET)
21/03/2020 • 20 minutes to read • Edit Online
La conexión a un servidor de bases de datos suele constar de varios pasos que requieren mucho tiempo. Se debe
establecer un canal físico, como un socket o una canalización con nombre, debe tener lugar el protocolo de enlace
con el servidor, se debe analizar la información de la cadena de conexión, el servidor debe autenticar la conexión,
se deben ejecutar comprobaciones para la inscripción en la transacción actual, etc.
En la práctica, la mayoría de las aplicaciones solamente utilizan unas cuantas configuraciones diferentes para las
conexiones. Esto significa que durante la ejecución de la aplicación, muchas conexiones idénticas se abrirán y
cerrarán de forma repetida. Para minimizar el costo de abrir conexiones, ADO.NET utiliza una técnica de
optimización denominada agrupaciónde conexiones.
La agrupación de conexiones reduce el número de veces que es necesario abrir nuevas conexiones. El agrupador
mantiene la propiedad de la conexión física. Para administrar las conexiones, mantiene un conjunto de conexiones
activas para cada configuración de conexión dada. Cada vez que un usuario llama a Open en una conexión, el
agrupador comprueba si hay una conexión disponible en el grupo. Si hay disponible una conexión agrupada, la
devuelve a la persona que llama en lugar de abrir una nueva. Cuando la aplicación llama a Close en la conexión,
el agrupador la devuelve al conjunto agrupado de conexiones activas en lugar de cerrarla. Una vez que la conexión
vuelve al grupo, ya está preparada para volverse a utilizar en la siguiente llamada a Open .
Solo se pueden agrupar conexiones con la misma configuración. ADO.NET mantiene varios grupos al mismo
tiempo, uno para cada configuración. Las conexiones se dividen en grupos por cadena de conexión, y por
identidad de Windows si se utiliza seguridad integrada. Las conexiones también se agrupan en función de si están
incluidas en una transacción. Cuando se usa ChangePassword, la instancia de SqlCredential afecta al grupo de
conexiones. Distintas instancias de SqlCredential usarán diferentes grupos de conexiones, incluso si el identificador
de usuario y la contraseña son iguales.
La agrupación de conexiones puede mejorar de forma considerable el rendimiento y la escalabilidad de la
aplicación. De forma predeterminada, la agrupación de conexiones está habilitada en ADO.NET. A menos que la
deshabilite explícitamente, el agrupador optimiza las conexiones a medida que se abren y cierran en la aplicación.
También puede proporcionar varios modificadores de cadena de conexión para controlar el comportamiento de
agrupación de conexiones. Para obtener más información, vea "Control de la agrupación de conexiones con
palabras clave de cadena de conexión" más adelante en este tema.
NOTE
Cuando se habilita la agrupación de conexiones, y si se produce un error de tiempo de expiración u otro error de inicio de
sesión, se producirá una excepción y los intentos de conexión posteriores producirán errores durante los cinco segundos
siguientes, el "período de bloqueo". Si la aplicación intenta conectarse dentro del período de bloqueo, se volverá a producir la
primera excepción. Los errores que se produzcan después de que finalice un período de bloqueo darán lugar a nuevos
períodos de bloqueo que serán el doble de largos que el período de bloqueo anterior, hasta un máximo de un minuto.
Si no se especifica MinPoolSize en la cadena de conexión o se especifica como cero, las conexiones del grupo se
cerrarán tras un período de inactividad. No obstante, si el MinPoolSize especificado es mayor que cero, el grupo
de conexión no se destruye hasta que se descarga el AppDomain y finaliza el proceso. El mantenimiento de grupos
inactivos o vacíos supone una sobrecarga mínima para el sistema.
NOTE
El grupo se borra automáticamente cuando se produce un error irrecuperable, como una conmutación por error.
Agregar conexiones
Para cada cadena de conexión única se crea un grupo de conexión. Cuando se crea un grupo, se crean y agregan al
grupo varios objetos de conexión y se satisface así el requisito de tamaño mínimo del grupo. Las conexiones se
agregan al grupo cuando es necesario, hasta el tamaño máximo del grupo especificado (100 es el valor
predeterminado), y se liberan de nuevo en el grupo cuando se cierran o eliminan.
Cuando se solicita un objeto SqlConnection, se obtiene del grupo si se encuentra disponible una conexión que se
pueda utilizar. Una conexión de este tipo debe estar sin utilizar, tener un contexto de transacción coincidente o no
estar asociada con ningún contexto de transacción y tener un vínculo válido al servidor.
El agrupador de conexiones satisface las solicitudes de conexión al reasignar las conexiones conforme se liberan
de nuevo en el grupo. Si se ha alcanzado el tamaño máximo del grupo y no hay disponible ninguna conexión que
se pueda utilizar, la solicitud se pone en la cola. A continuación, el concentrador intenta reclamar las conexiones
hasta que se agota el tiempo de espera (el valor predeterminado es 15 segundos). Si no puede satisfacer la
solicitud antes de que se agote el tiempo de espera de la conexión, se inicia una excepción.
Cau t i on
Se recomienda encarecidamente cerrar siempre la conexión cuando se termine de utilizar para que regrese al
grupo. Puede hacerlo mediante los Close Dispose métodos Connection o del objeto, o using abriendo todas las
Using conexiones dentro de una instrucción en C- o una instrucción en Visual Basic. Es posible que las conexiones
que no se cierran explícitamente no se puedan agregar ni puedan regresar al grupo. Para obtener más
información, vea Using Statement o How to: Dispose of a System Resource for Visual Basic.
NOTE
No llame a Close o a Dispose en un objeto Connection , un objeto DataReader o cualquier otro objeto administrado
en el método Finalize de la clase. En un finalizador, libere solo los recursos no administrados que pertenezcan
directamente a su clase. Si la clase no dispone de recursos no administrados, no incluya un método Finalize en la
definición de clase. Para obtener más información, consulte Recolección de elementos no utilizados.
Para obtener más información acerca de los eventos asociados con las conexiones de apertura y cierre, vea Clase
de evento de inicio de sesión de auditoría y Clase de evento de cierre de sesión de auditoría en la documentación
de SQL Server.
Fragmentación de grupos
La fragmentación de grupos es un problema común en muchas aplicaciones web en las que la aplicación puede
crear gran cantidad de grupos que no se liberan hasta que finaliza el proceso. El resultado es un gran número de
conexiones abiertas que consumen memoria, lo que da lugar a un bajo rendimiento.
Fragmentación de grupos debido a la seguridad integrada
Las conexiones se agrupan de acuerdo con la cadena de conexión y la identidad del usuario. Por lo tanto, si utiliza
autenticación básica o autenticación de Windows en el sitio web y un inicio de sesión de seguridad integrada,
obtendrá un grupo por usuario. Aunque de esta manera se mejora el rendimiento de las posteriores solicitudes de
base de datos de un solo usuario, ese usuario no podrá aprovechar las conexiones realizadas por otros usuarios.
Además, como resultado habrá una conexión como mínimo por usuario al servidor de bases de datos. Se trata de
un efecto secundario de una determinada arquitectura de aplicaciones web que los desarrolladores deben sopesar
frente a los requisitos de seguridad y auditoría.
Fragmentación de grupos debido a muchas bases de datos
Muchos proveedores de acceso a Internet hospedan varios sitios web en un único servidor. Puede que utilicen una
sola base de datos para confirmar un inicio de sesión de autenticación de formularios y luego abran una conexión
a una base de datos específica para ese usuario o grupo de usuarios. La conexión a la base de datos de
autenticación es agrupada y utilizada por todo el mundo. Sin embargo, hay un grupo independiente de conexiones
con cada base de datos, lo que implica un aumento del número de conexiones con el servidor.
Este es también un efecto secundario del diseño de la aplicación. Existe, sin embargo, una forma relativamente
sencilla de evitarlo sin comprometer la seguridad cuando se establece conexión con SQL Server. En lugar de
realizar una conexión a una base de datos diferente por cada usuario o grupo, realice una conexión a la misma
base de datos en el servidor y, a continuación, ejecute la instrucción USE de Transact-SQL para cambiar a la base
de datos deseada. En el siguiente fragmento de código se muestra la creación de una conexión inicial con la base
de datos master y el cambio a la base de datos deseada especificada en la variable de cadena databaseName .
Consulte también
Agrupar conexiones
SQL Server y ADO.NET
Contadores de rendimiento
Información general de ADO.NET
Agrupación de conexiones de OLE DB, ODBC y
Oracle
08/01/2020 • 11 minutes to read • Edit Online
OleDb
El proveedor de datos .NET Framework para OLE DB agrupa automáticamente las conexiones mediante la
agrupación de sesiones OLE DB. Se pueden utilizar argumentos de cadena de conexión para habilitar o
deshabilitar servicios OLE DB, incluida la agrupación. Por ejemplo, la siguiente cadena de conexión deshabilita la
agrupación de sesiones OLE DB y la inscripción automática de transacciones.
Se recomienda cerrar siempre o eliminar una conexión cuando termine de utilizarla, para que la conexión pueda
regresar al grupo. Es posible que las conexiones que no se cierran explícitamente no puedan regresar al grupo. Por
ejemplo, una conexión que se ha salido del ámbito pero que no se ha cerrado explícitamente solo se devolverá al
grupo de conexión si se ha alcanzado el tamaño máximo del grupo y la conexión aún es válida.
Para obtener más información sobre OLE DB la agrupación de sesiones o de recursos, y cómo deshabilitar la
agrupación invalidando los valores predeterminados del servicio de proveedor de OLE DB, consulte la Guía del
programador de OLE DB.
ODBC
La agrupación de conexiones para el proveedor de datos .NET Framework para ODBC se administra a través del
Administrador de controladores ODBC que se utiliza en la conexión, y que no está influido por dicho proveedor.
Para habilitar o deshabilitar la agrupación de conexiones, abra el Administrador de orígenes de datos ODBC
en la carpeta Herramientas administrativas del panel de control. La pestaña agrupación de conexiones permite
especificar parámetros de agrupación de conexiones para cada controlador ODBC instalado. Los cambios en la
agrupación de conexiones para un controlador ODBC específico afectan a todas las aplicaciones que utilizan ese
controlador ODBC.
OracleClient
El proveedor de datos .NET Framework para Oracle ofrece agrupación automática de conexiones para la aplicación
cliente de ADO.NET. También puede suministrar varios modificadores de cadena de conexión para controlar el
comportamiento de agrupación de conexiones (vea "Control de la agrupación de conexiones con palabras clave
de cadena de conexión", más adelante en este tema).
Crear y asignar grupos
Cuando se abre una conexión, se crea un grupo de conexión basado en un algoritmo de coincidencia exacta que
asocia el grupo con la cadena de conexión de la conexión. Cada grupo de conexión se asocia con una cadena de
conexión distinta. Si se abre una nueva conexión y la cadena de conexión no coincide exactamente con un grupo
existente, se crea un nuevo grupo.
Una vez creados, los grupos de conexión no se destruyen hasta que finaliza el proceso activo. Mantener grupos
inactivos o vacíos consume muy pocos recursos del sistema.
Adición de conexiones
Para cada cadena de conexión única se crea un grupo de conexión. Cuando se crea un grupo, se crean y agregan al
grupo varios objetos de conexión y se satisface así el requisito de tamaño mínimo del grupo. Las conexiones se
agregan al grupo cuando es necesario, hasta el tamaño máximo del grupo.
Cuando se solicita un objeto OracleConnection, se obtiene del grupo si se encuentra disponible una conexión que
se pueda utilizar. Una conexión de este tipo debe estar sin utilizar en ese momento, tener un contexto de
transacción coincidente o no estar asociada con ningún contexto de transacción, y tener un vínculo válido al
servidor.
Si se ha alcanzado el tamaño máximo del grupo y no hay disponible ninguna conexión que se pueda utilizar, la
solicitud se pone en la cola. El concentrador de conexión satisface estas solicitudes al reasignar las conexiones
conforme se liberan de nuevo en el grupo, lo cual ocurre y se liberan de nuevo en el grupo cuando se cierran o
eliminan.
Eliminación de conexiones
El agrupador de conexiones quita una conexión del grupo después de que haya estado inactiva durante un
período de tiempo prolongado o si el concentrador detecta que se ha roto la conexión con el servidor. Esto solo se
puede detectar después de intentar comunicarse con el servidor. Si se encuentra que una conexión ya no está
conectada al servidor, se marca como no válida. El concentrador de conexión analiza periódicamente los grupos en
busca de objetos que se han liberado en el grupo y marcado como no válidos. Luego, estas conexiones se quitan
de forma permanente.
Si existe una conexión a un servidor que ha desaparecido, se puede extraer del grupo si el concentrador de
conexión no ha detectado la conexión rota y la ha marcado como no válida. Cuando esto se produce, se genera
una excepción. No obstante, aun así deberá cerrar la conexión para liberarla de nuevo en el grupo.
No llame a Close o a Dispose en un objeto Connection , un objeto DataReader o cualquier otro objeto
administrado en el método Finalize de la clase. En un finalizador, libere solo los recursos no administrados que
pertenezcan directamente a su clase. Si la clase no dispone de recursos no administrados, no incluya un método
Finalize en la definición de clase. Para obtener más información, consulte recolección de elementos no
utilizados.
Compatibilidad con transacciones
Las conexiones se extraen del grupo y se asignan en función del contexto de transacción. Es necesario que el
subproceso solicitante y la conexión asignada coincidan. Por lo tanto, cada grupo de conexiones se subdivide en
conexiones sin contexto de transacción asociado y en N subdivisiones, cada una de las cuales contiene conexiones
con un contexto de transacción determinado.
Cuando se cierra una conexión, se libera de nuevo en el grupo y en la subdivisión adecuada en función de su
contexto de transacción. Por lo tanto, puede cerrar la conexión sin generar un error, incluso aunque aún haya
pendiente una transacción distribuida. Esto le permite confirmar o anular la transacción distribuida más adelante.
Controlar la agrupación de conexiones con palabras clave de cadena de conexión
La propiedad ConnectionString del objeto OracleConnection admite pares clave-valor de cadena de conexión que
se pueden utilizar para ajustar el comportamiento de la lógica de agrupación de conexiones.
En la siguiente tabla se describen los valores ConnectionString que puede utilizar para ajustar el comportamiento
de agrupación de conexiones.
NAME P REDET ERM IN A DO DESC RIP C IÓ N
Vea también
Agrupación de conexiones
Performance Counters
Información general sobre ADO.NET
Comandos y parámetros
23/10/2019 • 3 minutes to read • Edit Online
Una vez establecida una conexión a un origen de datos, puede ejecutar comandos y devolver resultados desde el
mismo mediante un objeto DbCommand. Para crear un comando, puede utilizar uno de los constructores de
comando del proveedor de datos .NET Framework con el que esté trabajando. Los constructores pueden aceptar
argumentos opcionales, como una instrucción SQL para ejecutar en el origen de datos, un objeto DbConnection o
un objeto DbTransaction. También puede configurar dichos objetos como propiedades del comando. También
puede crear un comando para una determinada conexión mediante el método CreateCommand de un objeto
DbConnection . La instrucción SQL que ejecuta el comando se puede configurar mediante la propiedad
CommandText.
Cada proveedor de datos .NET Framework incluido en .NET Framework cuenta con un objeto Command : El
proveedor de datos .NET Framework para OLE DB incluye un objeto OleDbCommand, el proveedor de datos .NET
Framework para SQL Server incluye un objeto SqlCommand, el proveedor de datos .NET Framework para ODBC
incluye un objeto OdbcCommand y el proveedor de datos .NET Framework para Oracle incluye un objeto
OracleCommand.
En esta sección
Ejecución de un comando
Describe el objeto Command de ADO.NET, así como la forma de utilizarlo para ejecutar consultas y comandos con
respecto a un origen de datos.
Configuración de parámetros y tipos de datos de parámetros
Describe el trabajo con parámetros Command , incluidos dirección, tipo de datos y sintaxis de parámetros.
Generación de comandos con objetos CommandBuilder
Describe cómo utilizar generadores de comandos para generar automáticamente comandos INSERT, UPDATE y
DELETE para un DataAdapter que tiene un comando SELECT de tabla única.
Obtención de un valor único de una base de datos
Describe cómo utilizar el método ExecuteScalar de un objeto Command para devolver un único valor desde una
consulta de base de datos.
Uso de comandos para modificar datos
Describe cómo se utiliza un proveedor de datos para ejecutar procedimientos almacenados o instrucciones de
lenguaje de definición de datos (DDL).
Vea también
Objetos DataAdapter y DataReader
Objetos DataSet, DataTable y DataView
Conexión a un origen de datos
Información general sobre ADO.NET
Ejecutar un comando
23/10/2019 • 4 minutes to read • Edit Online
Cada proveedor de datos .NET Framework incluido en .NET Framework dispone de su propio objeto command que
hereda de DbCommand. El proveedor de datos .NET Framework para OLE DB incluye un objeto OleDbCommand,
el proveedor de datos .NET Framework para SQL Server incluye un objeto SqlCommand, el proveedor de datos
.NET Framework para ODBC incluye un objeto OdbcCommand y el proveedor de datos .NET Framework para
Oracle incluye un objeto OracleCommand. Cada uno de estos objetos expone métodos para ejecutar comandos
que se basan en el tipo de comando y el valor devuelto deseado, tal como se describe en la tabla siguiente.
GET - H EL P VA LO R DEVUELTO
Cada objeto command fuertemente tipado admite también una enumeración CommandType que especifica cómo
se interpreta una cadena de comando, tal como se describe en la tabla siguiente.
C O M M A N DT Y P E DESC RIP C IÓ N
Ejemplo
En el ejemplo de código siguiente se muestra cómo se crea un objeto SqlCommand para ejecutar un
procedimiento almacenado mediante el establecimiento de sus propiedades. Para especificar el parámetro de
entrada del procedimiento almacenado se usa un objeto SqlParameter. El comando se ejecuta con el método
ExecuteReader y el resultado de SqlDataReader se muestra en la ventana de consola.
static void GetSalesByCategory(string connectionString,
string categoryName)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
// Create the command and set its properties.
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = "SalesByCategory";
command.CommandType = CommandType.StoredProcedure;
If reader.HasRows Then
Do While reader.Read()
Console.WriteLine("{0}: {1:C}", _
reader(0), reader(1))
Loop
Else
Console.WriteLine("No rows returned.")
End If
End Using
End Using
End Sub
Vea también
Comandos y parámetros
Objetos DataAdapter y DataReader
Información general sobre ADO.NET
Configurar parámetros y tipos de datos de
parámetro
23/10/2019 • 19 minutes to read • Edit Online
Los objetos de comando usan parámetros para pasar valores a instrucciones SQL o procedimientos almacenados
que permiten realizar operaciones de comprobación de tipos y validación. A diferencia del texto de comando, la
entrada de parámetros se trata como un valor literal, y no como código ejecutable. De esta forma, se protege
contra ataques por "inyección de código SQL", en los que un atacante inserta un comando que pone en peligro la
seguridad del servidor en una instrucción SQL.
Los comandos parametrizados también pueden mejorar el rendimiento de ejecución de la consulta, ya que ayudan
al servidor de bases de datos a que haga coincidir precisamente el comando entrante con un plan de consulta
almacenado en caché adecuado. Para obtener más información, consulte Plan de almacenamiento en caché en
ejecución y volver a utilizar y parámetros y reutilización de Plan de ejecución. Además de las ventajas en la
seguridad y el rendimiento, los comandos con parámetros proporcionan un método práctico para organizar los
valores que se pasan a un origen de datos.
Para crear un objeto DbParameter , se puede usar su constructor o bien se puede agregar a DbParameterCollection
mediante una llamada al método Add de la colección DbParameterCollection . El método Add acepta como
entrada argumentos del constructor o cualquier objeto de parámetro ya existente, en función del proveedor de
datos.
T IP O DE . N ET
F RA M EW O RK DBT Y P E SQ L DBT Y P E O L EDBT Y P E O DB C T Y P E O RA C L ET Y P E
NOTE
Las conversiones de valores de tipo decimal en otros tipos de valor son conversiones de restricción que redondean el valor
decimal al valor entero más próximo a cero. Si el resultado de la conversión no puede representarse en el tipo de destino, se
produce OverflowException .
NOTE
Cuando se envía un valor de parámetro null al servidor, debe especificar DBNull, no null ( Nothing en Visual Basic). El
valor nulo en el sistema es un objeto vacío que no tiene ningún valor. Para representar los valores nulos, se usaDBNull . Para
obtener más información sobre valores nulos de base de datos, consulte Handling Null Values.
NOTE
La derivación de información de parámetros afecta al rendimiento, ya que precisa un viaje adicional de ida y vuelta (round
trip) al origen de datos para recuperar la información. Si la información de los parámetros se conoce en tiempo de diseño, se
puede mejorar el rendimiento de la aplicación si se establecen los parámetros con los valores correspondientes de forma
explícita.
Para obtener más información, consulte generar comandos con objetos CommandBuilder.
NOTE
Las instrucciones con parámetros se ejecutan en el servidor utilizando sp_executesql, ; esto permite volver a utilizar el
plan de consultas. Los cursores o las variables locales del lote de sp_executesql no son visibles para el lote que llama a
sp_executesql . Los cambios en el contexto de base de datos solo se mantienen hasta el final de la instrucción
sp_executesql . Para obtener más información, consulte sp_executesql (Transact-SQL).
Cuando se usan parámetros con SqlCommand para ejecutar un procedimiento almacenado de SQL Server, los
nombres de los parámetros agregados a la colección Parameters deben coincidir con los nombres de los
marcadores de parámetro del procedimiento almacenado. El proveedor de datos de .NET Framework para SQL
Server no es compatible con el marcador de posición de signo de interrogación (?) para pasar parámetros a una
instrucción SQL o un procedimiento almacenado. Este proveedor trata los parámetros del procedimiento
almacenado como parámetros con nombre y busca marcadores de parámetros coincidentes. Por ejemplo, el
procedimiento almacenado CustOrderHist se define usando un parámetro denominado @CustomerID . Cuando el
código ejecuta el procedimiento almacenado, también debe usar un parámetro denominado @CustomerID .
Ejemplo
En este ejemplo se muestra cómo llamar a un procedimiento almacenado de SQL Server en la base de datos de
ejemplo Northwind . El nombre del procedimiento almacenado es dbo.SalesByCategory e incluye un parámetro de
entrada denominado @CategoryName con el tipo de datos nvarchar(15) . El código crea una nueva clase
SqlConnection dentro de un bloque en uso, de forma que la conexión se cierre cuando finalice el procedimiento.
Se crean los objetos SqlCommand y SqlParameter , y se establecen sus propiedades. SqlDataReader ejecuta
SqlCommand y devuelve el conjunto de resultados del procedimiento almacenado, mostrándolos en la ventana de
consola.
NOTE
En lugar de crear objetos SqlCommand y SqlParameter y, a continuación, establecer propiedades en instrucciones
independientes, puede usar uno de los constructores sobrecargados para establecer varias propiedades en una única
instrucción.
If reader.HasRows Then
Do While reader.Read()
Console.WriteLine("{0}: {1:C}", _
reader(0), reader(1))
Loop
Else
Console.WriteLine("No rows returned.")
End If
End Using
End Using
End Sub
Por eso, el orden en que se agregan los objetos Parameter a la colección Parameters debe coincidir exactamente
con la posición del marcador de posición de interrogación de cierre correspondiente al parámetro.
Ejemplo de OleDb
Dim command As OleDbCommand = New OleDbCommand( _
"SampleProc", connection)
command.CommandType = CommandType.StoredProcedure
parameter = command.Parameters.Add( _
"@InputParm", OleDbType.VarChar, 12)
parameter.Value = "Sample Value"
parameter = command.Parameters.Add( _
"@OutputParm", OleDbType.VarChar, 28)
parameter.Direction = ParameterDirection.Output
parameter = command.Parameters.Add(
"@InputParm", OleDbType.VarChar, 12);
parameter.Value = "Sample Value";
parameter = command.Parameters.Add(
"@OutputParm", OleDbType.VarChar, 28);
parameter.Direction = ParameterDirection.Output;
Ejemplo de Odbc
Dim command As OdbcCommand = New OdbcCommand( _
"{ ? = CALL SampleProc(?, ?) }", connection)
command.CommandType = CommandType.StoredProcedure
parameter = command.Parameters.Add( _
"@InputParm", OdbcType.VarChar, 12)
parameter.Value = "Sample Value"
parameter = command.Parameters.Add( _
"@OutputParm", OdbcType.VarChar, 28)
parameter.Direction = ParameterDirection.Output
OdbcCommand command = new OdbcCommand( _
"{ ? = CALL SampleProc(?, ?) }", connection);
command.CommandType = CommandType.StoredProcedure;
parameter = command.Parameters.Add( _
"@InputParm", OdbcType.VarChar, 12);
parameter.Value = "Sample Value";
parameter = command.Parameters.Add( _
"@OutputParm", OdbcType.VarChar, 28);
parameter.Direction = ParameterDirection.Output;
Vea también
Comandos y parámetros
Parámetros de DataAdapter
Asignaciones de tipos de datos en ADO.NET
Información general sobre ADO.NET
Generar comandos con objetos CommandBuilder
21/03/2020 • 13 minutes to read • Edit Online
Cuando la propiedad SelectCommand se especifica de forma dinámica en tiempo de ejecución, por ejemplo a través
de una herramienta de consulta que acepta un comando de texto del usuario, existe la posibilidad de que no se
pueda especificar adecuadamente en tiempo de diseño el comando InsertCommand , UpdateCommand o
DeleteCommand correspondiente. Si el objeto DataTable se asigna a una única tabla de base de datos o se genera a
partir de ella, puede utilizar el objeto DbCommandBuilder para generar automáticamente las propiedades
DeleteCommand , InsertCommand y UpdateCommand de DbDataAdapter.
El requisito mínimo para que la generación automática de comandos funcione correctamente consiste en
establecer la propiedad SelectCommand . El esquema de tabla que recupera la propiedad SelectCommand determina
la sintaxis de las instrucciones INSERT, UPDATE y DELETE generadas automáticamente.
DbCommandBuilder debe ejecutar SelectCommand con el objeto de devolver los metadatos necesarios para
construir los comandos SQL INSERT, UPDATE y DELETE. Por eso es necesario realizar un viaje adicional al origen de
datos, con el consiguiente efecto adverso en el rendimiento. Para mejorar el rendimiento, debe especificar los
comandos de forma explícita, en lugar de utilizar DbCommandBuilder.
SelectCommand también debe devolver como mínimo una clave principal o una columna única. Si no hay ninguna,
se genera una excepción InvalidOperation y no se genera ningún comando.
Cuando se asocia con un objeto DataAdapter , DbCommandBuilder genera automáticamente las propiedades
InsertCommand , UpdateCommand y DeleteCommand del objeto DataAdapter si son referencias nulas. Si ya existe algún
objeto Command para una propiedad, se utilizará el objeto Command existente.
Las vistas de bases de datos creadas al unir una o varias tablas no se consideran una tabla única de base de datos.
En este caso no puede utilizar DbCommandBuilder para generar comandos automáticamente y deberá
especificarlos de manera explícita. Para obtener información sobre cómo establecer DataSet explícitamente
comandos para resolver actualizaciones de una copia posterior en el origen de datos, vea Actualizar orígenes de
datos con DataAdapters.
Es posible que desee asignar parámetros de salida a la fila actualizada de un DataSet . Una tarea habitual consiste
en recuperar, a partir del origen de datos, el valor de un campo de identidad de generación automática o una
marca de tiempo. DbCommandBuilder no asigna de forma predeterminada los parámetros de salida a las
columnas de una fila actualizada. En este caso, debe especificar el comando de forma explícita. Para obtener un
ejemplo de asignación de un campo de identidad generado automáticamente a una columna de una fila insertada,
vea Recuperar valores de identidad o numeración automática.
GET - H EL P REGL A
InsertCommand Inserta una fila en el origen de datos para todas las filas de la
tabla con una RowState con el valor Added. Inserta valores
para todas las columnas actualizables, pero no para
determinadas columnas como identidades, expresiones o
marcas de tiempo.
GET - H EL P REGL A
Modificar SelectCommand
Es posible que se inicie una excepción si modifica valor CommandText de SelectCommand después de generar
automáticamente los comandos INSERT, UPDATE o DELETE. Si el valor SelectCommand.CommandText modificado
contiene información del esquema que sea incoherente con el valor SelectCommand.CommandText utilizado en el
momento de la generación automática de los comandos de inserción, actualización o eliminación, las futuras
llamadas al método DataAdapter.Update pueden tratar de obtener acceso a columnas que ya no existen en la tabla
actual a la que hace referencia SelectCommand , con lo que se iniciará una excepción.
Puede actualizar la información del esquema que utiliza CommandBuilder para generar automáticamente los
comandos; para ello, basta con llamar al método RefreshSchema de CommandBuilder .
Si desea conocer el comando generado automáticamente, puede obtener una referencia a los comandos
generados automáticamente mediante los métodos GetInsertCommand , GetUpdateCommand y GetDeleteCommand del
objeto CommandBuilder y la comprobación de la propiedad CommandText del comando asociado.
En el ejemplo de código siguiente se escribe en la consola el comando de actualización generado
automáticamente.
Console.WriteLine(builder.GetUpdateCommand().CommandText)
Console.WriteLine(builder.GetUpdateCommand().CommandText);
En el siguiente ejemplo se vuelve a crear la tabla Customers en el conjunto de datos custDS . El RefreshSchema
se llama al método para actualizar los comandos generados automáticamente con esta nueva información de
columna.
custDS.Tables.Remove(custDS.Tables("Customers"))
adapter.Fill(custDS, "Customers")
custDS.Tables.Remove(custDS.Tables["Customers"]);
adapter.Fill(custDS, "Customers");
Consulte también
Comandos y parámetros
Ejecución de un comando
DbConnection, DbCommand y DbException
Información general de ADO.NET
Obtener un valor único de una base de datos
23/10/2019 • 2 minutes to read • Edit Online
En ocasiones se debe devolver información de bases de datos consistente en un único valor, en lugar de una tabla o
un flujo de datos. Por ejemplo, puede que desee devolver el resultado de una función de agregado como Count (*),
SUM (Price) o AVG (quantity). El objeto Command proporciona la capacidad de devolver valores únicos mediante
el método ExecuteScalar . El método ExecuteScalar devuelve, como un valor escalar, el valor de la primera
columna de la primera fila del conjunto de resultados.
El ejemplo de código siguiente inserta un valor nuevo en la base de datos utilizando SqlCommand. El método
ExecuteScalar se utiliza para devolver el valor de columna de identidad para el registro insertado.
Return newProdID
End Function
Vea también
Comandos y parámetros
Ejecución de un comando
DbConnection, DbCommand y DbException
Información general sobre ADO.NET
Usar comandos para modificar datos
23/10/2019 • 2 minutes to read • Edit Online
Mediante un proveedor de datos .NET Framework puede ejecutar procedimientos almacenados o instrucciones de
lenguaje de definición de datos, como CREATE TABLE y ALTER COLUMN, para manipular los esquemas de una base
de datos o catálogo. Estos comandos no devuelven filas como lo haría una consulta, por lo que el objeto de
comando proporciona un ExecuteNonQuer y para procesarlos.
Además de usar ExecuteNonQuer y para modificar el esquema, también puede utilizar este método para
procesar instrucciones SQL que modifican datos pero que no devuelven filas, como INSERT, Update y DELETE.
Aunque el método ExecuteNonQuer y no devuelve las filas, los parámetros de entrada y salida y los valores
devueltos se pueden pasar y devolver a través de la colección Parameters del objeto Command .
En esta sección
Actualización de datos de un origen de datos
Describe la forma de ejecutar comandos o procedimientos almacenados que modifican datos en una base de
datos.
Realización de operaciones de catálogo
Describe la forma de ejecutar comandos que modifican esquemas de la base de datos.
Vea también
Recuperar y modificar datos en ADO.NET
Comandos y parámetros
Información general sobre ADO.NET
Actualizar datos de un origen de datos
21/03/2020 • 3 minutes to read • Edit Online
Las instrucciones SQL que modifican datos (por ejemplo INSERT, UPDATE o DELETE) no devuelven ninguna fila. De
la misma forma, muchos procedimientos almacenados realizan alguna acción pero no devuelven filas. Para
ejecutar comandos que no devuelven filas, cree un objeto Command con el comando SQL adecuado y una
conexión , incluidos los parámetros necesarios. Ejecute el comando con el método ExecuteNonQuer y del
objeto Command.
El Método ExecuteNonQuer y devuelve un entero que representa el número de filas afectadas por la instrucción
o el procedimiento almacenado que se ejecutó. Si se ejecutan varias instrucciones, el valor devuelto es la suma de
los registros afectados por todas las instrucciones ejecutadas.
Ejemplo
En el ejemplo de código siguiente se ejecuta una instrucción INSERT para insertar un registro en una base de datos
mediante ExecuteNonQuer y .
En el ejemplo de código siguiente se ejecuta el procedimiento almacenado creado por el código de ejemplo en
Realizar operacionesde catálogo . El procedimiento almacenado no devuelve ninguna fila, por lo que se usa el
método ExecuteNonQuer y, pero el procedimiento almacenado recibe un parámetro de entrada y devuelve un
parámetro de salida y un valor devuelto.
Para OleDbCommand el objeto, el parámetro ReturnValue debe agregarse primero a la colección Parameters.
' Assumes connection is a valid SqlConnection.
Dim command As SqlCommand = _
New SqlCommand("InsertCategory" , connection)
command.CommandType = CommandType.StoredProcedure
parameter = command.Parameters.Add( _
"@CategoryName", SqlDbType.NChar, 15)
parameter = command.Parameters.Add(
"@CategoryName", SqlDbType.NChar, 15);
Consulte también
Uso de comandos para modificar datos
Actualizar orígenes de datos con objetos DataAdapter
Comandos y parámetros
Información general de ADO.NET
Realizar operaciones de catálogo
21/03/2020 • 2 minutes to read • Edit Online
Para ejecutar un comando para modificar una base de datos o un catálogo, como la instrucción CREATE TABLE o
CREATE PROCEDURE, cree un objeto Command utilizando las instrucciones SQL adecuadas y un objeto
Connection. Ejecute el comando con el método ExecuteNonQuer y del objeto Command.
En el ejemplo de código siguiente se crea un procedimiento almacenado en una base de datos de Microsoft SQL
Server.
Consulte también
Uso de comandos para modificar datos
Comandos y parámetros
Información general de ADO.NET
Objetos DataAdapter y DataReader
23/10/2019 • 4 minutes to read • Edit Online
Puede usar ADO.NET DataReader para recuperar una secuencia de datos de solo lectura y de solo avance desde
una base de datos. Los resultados se devuelven cuando se ejecuta la consulta y se almacenan en el búfer de red
en el cliente hasta que se solicitan mediante el método Read del DataReader . El uso de DataReader puede
aumentar el rendimiento de la aplicación al recuperar los datos tan pronto como estén disponibles y, de forma
predeterminada, almacenar solo una fila a la vez en la memoria, lo que reduce la sobrecarga del sistema.
Un DataAdapter se utiliza para recuperar datos de un origen de datos y llenar tablas con un DataSet.
DataAdapter también resuelve los cambios realizados en DataSet de vuelta al origen de datos. Mediante el
objeto DataAdapter del proveedor de datos .NET Framework, Connection se conecta a un origen de datos y
utiliza objetos Command para recuperar datos del origen de datos y resolver los cambios a dicho origen.
Cada proveedor de datos .NET Framework incluido con .NET Framework tiene un objeto DbDataReader y un
objeto DbDataAdapter, el proveedor de datos .NET Framework para OLE DB incluye un objeto OleDbDataReader
y un objeto OleDbDataAdapter, el proveedor de datos .NET Framework para SQL Server incluye un objeto
SqlDataReader y un objeto SqlDataAdapter, el proveedor de datos .NET Framework para ODBC incluye un objeto
OdbcDataReader y un objeto OdbcDataAdapter, y el proveedor de datos .NET Framework para Oracle incluyes
un objeto OracleDataReader y un objeto OracleDataAdapter.
En esta sección
Recuperación de datos utilizando un objeto DataReader
Describe el objeto datareader ADO.net y cómo usarlo para devolver una secuencia de resultados de un origen
de datos.
Rellenar un conjunto de datos desde un objeto DataAdapter
Describe cómo llenar un DataSet de tablas, columnas y filas mediante un DataAdapter .
Parámetros de DataAdapter
Describe cómo utilizar parámetros con las propiedades de comando de DataAdapter , lo que incluye cómo
asignar el contenido de una columna de DataSet a un parámetro de comando.
Agregar restricciones existentes a un conjunto de datos
Describe cómo agregar restricciones existentes a un DataSet .
Correspondencias de DataTable y DataColumn en un objeto DataAdapter
Describe cómo configurar DataTableMappings y ColumnMappings para DataAdapter .
Paginación de un resultado de consulta
Proporciona un ejemplo de cómo ver los resultados de una consulta como páginas de datos.
Actualizar orígenes de datos con objetos DataAdapter
Describe cómo se utiliza DataAdapter para resolver modificaciones en DataSet en la base de datos.
Control de eventos de DataAdapter
Describe los eventos de DataAdapter y cómo utilizarlos.
Realización de operaciones por lotes utilizando objetos DataAdapter
Describe cómo mejorar el rendimiento de la aplicación mediante la reducción del número de viajes de ida y
vuelta (round trip) al servidor SQL Server al aplicar las actualizaciones desde el DataSet .
Vea también
Conexión a un origen de datos
Comandos y parámetros
Transacciones y simultaneidad
Objetos DataSet, DataTable y DataView
Información general sobre ADO.NET
Recuperar datos mediante un DataReader
21/03/2020 • 13 minutes to read • Edit Online
Para recuperar datos mediante un DataReader , cree una instancia de la Command objeto y, a continuación, cree
un DataReader mediante una llamada a Command.ExecuteReader para recuperar filas de un origen de datos.
DataReader proporciona un flujo de datos sin búfer que permite que la lógica de procedimientos procese
eficazmente los resultados de un origen de datos secuencialmente. DataReader es una buena opción cuando se
recuperan grandes cantidades de datos porque los datos no se almacenan en caché en la memoria.
En el ejemplo siguiente se muestra reader el uso de command un DataReader , donde representa un DataReader
válido y representa un objeto Command válido.
reader = command.ExecuteReader();
reader = command.ExecuteReader()
Utilice el método DataReader.Read para obtener una fila de los resultados de la consulta. Puede tener acceso a
cada columna de la fila devuelta pasando el nombre o el número ordinal de la columna al DataReader . Sin
embargo, para obtener el mejor rendimiento, DataReader proporciona una serie de métodos que permiten
tener acceso a los valores de columna en sus tipos de datos nativos (GetDateTime , GetDouble , GetGuid ,
GetInt32 , etc.). Para obtener una lista de métodos de descriptor OleDbDataReader de SqlDataReaderacceso con
tipo para DataReaders específicos del proveedor de datos , vea y . El uso de los métodos de descriptor de acceso
con tipo cuando conoce el tipo de datos subyacente reduce la cantidad de conversión de tipos necesaria al
recuperar el valor de columna.
En el ejemplo siguiente se recorre en iteración un DataReader objeto y devuelve dos columnas de cada fila.
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
reader.GetString(1));
}
}
else
{
Console.WriteLine("No rows found.");
}
reader.Close();
}
}
Private Sub HasRows(ByVal connection As SqlConnection)
Using connection
Dim command As SqlCommand = New SqlCommand( _
"SELECT CategoryID, CategoryName FROM Categories;", _
connection)
connection.Open()
If reader.HasRows Then
Do While reader.Read()
Console.WriteLine(reader.GetInt32(0) _
& vbTab & reader.GetString(1))
Loop
Else
Console.WriteLine("No rows found.")
End If
reader.Close()
End Using
End Sub
Cerrar el DataReader
Llame siempre a la Close método cuando haya terminado de usar el DataReader objeto.
Si el comando contiene parámetros de salida o valores devueltos, esos valores no están disponibles hasta que
se cierra DataReader.
Mientras un DataReader está abierto, la conexión está en uso exclusivamente por ese DataReader . No puede
ejecutar ningún comando para Connection , incluida la creación de otro DataReader , hasta que se cierre el
DataReader original.
NOTE
No llame a Close o Dispose en una conexión , un DataReader o cualquier otro objeto administrado en el Finalize
método de la clase. En un finalizador, libere solo los recursos no administrados que pertenezcan directamente a su clase. Si
la clase no posee ningún recurso no administrado, no incluya un método Finalize en la definición de clase. Para obtener
más información, consulte Recolección de elementos no utilizados.
while (reader.HasRows)
{
Console.WriteLine("\t{0}\t{1}", reader.GetName(0),
reader.GetName(1));
while (reader.Read())
{
Console.WriteLine("\t{0}\t{1}", reader.GetInt32(0),
reader.GetString(1));
}
reader.NextResult();
}
}
}
Do While reader.HasRows
Console.WriteLine(vbTab & reader.GetName(0) _
& vbTab & reader.GetName(1))
Do While reader.Read()
Console.WriteLine(vbTab & reader.GetInt32(0) _
& vbTab & reader.GetString(1))
Loop
reader.NextResult()
Loop
End Using
End Sub
connection.Open()
Do While custReader.Read()
Console.WriteLine("Orders for " & custReader.GetString(1))
' custReader.GetString(1) = CompanyName
Do While orderReader.Read()
Console.WriteLine(vbTab & orderReader.GetInt32(1))
' orderReader.GetInt32(1) = OrderID
Loop
orderReader.Close()
End Using
Loop
' Make sure to always close readers and connections.
custReader.Close()
End Using
End Using
End Using
using (OleDbConnection connection = new OleDbConnection(
"Provider=MSDataShape;Data Provider=SQLOLEDB;" +
"Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind"))
{
using (OleDbCommand custCMD = new OleDbCommand(
"SHAPE {SELECT CustomerID, CompanyName FROM Customers} " +
"APPEND ({SELECT CustomerID, OrderID FROM Orders} AS CustomerOrders " +
"RELATE CustomerID TO CustomerID)", connection))
{
connection.Open();
while (custReader.Read())
{
Console.WriteLine("Orders for " + custReader.GetString(1));
// custReader.GetString(1) = CompanyName
while (orderReader.Read())
Console.WriteLine("\t" + orderReader.GetInt32(1));
// orderReader.GetInt32(1) = OrderID
orderReader.Close();
}
}
// Make sure to always close readers and connections.
custReader.Close();
}
}
}
El código siguiente OracleCommand crea un que devuelve los REF CURSOR del paquete OracleType.Cursor de
OracleCommand.Parameters Oracle anterior agregando dos parámetros de tipo a la colección.
El código siguiente devuelve los resultados Read() del NextResult() comando OracleDataReaderanterior mediante
los métodos y del archivo . Los parámetros REF CURSOR se devuelven en orden.
oraConn.Open()
Do While reader.Read()
Console.WriteLine("{0}" & vbTab & "{1}, {2}", reader.GetOracleNumber(0), reader.GetString(1),
reader.GetString(2))
Loop
reader.NextResult()
Do While reader.Read()
Console.WriteLine("{0}" & vbTab & "{1}", reader.GetOracleNumber(0), reader.GetString(1))
Loop
' Make sure to always close readers and connections.
reader.Close()
oraConn.Close()
oraConn.Open();
Console.WriteLine("\nEmp ID\tName");
while (reader.Read())
Console.WriteLine("{0}\t{1}, {2}", reader.GetOracleNumber(0), reader.GetString(1), reader.GetString(2));
reader.NextResult();
Console.WriteLine("\nDept ID\tName");
while (reader.Read())
Console.WriteLine("{0}\t{1}", reader.GetOracleNumber(0), reader.GetString(1));
// Make sure to always close readers and connections.
reader.Close();
oraConn.Close();
En el ejemplo siguiente se DataSet utiliza el comando anterior para rellenar a con los resultados del paquete de
Oracle.
adapter.Fill(ds)
adapter.Fill(ds);
NOTE
Para evitar una OverflowException , se recomienda controlar también cualquier conversión del tipo Oracle NUMBER a
DataRowun tipo válido de .NET Framework antes de almacenar el valor en un archivo . Puede usar FillError el evento para
determinar si se ha producido una excepción OverflowException. Para obtener más FillError información sobre el
evento, vea Controlar eventos DataAdapter.
Consulte también
Objetos DataAdapter y DataReader
Comandos y parámetros
Recuperación de información del esquema de la base de datos
Información general de ADO.NET
Rellenar un conjunto de datos desde un objeto
DataAdapter
21/03/2020 • 18 minutes to read • Edit Online
El DataSet ADO.NET es una representación residente en memoria de datos que proporciona un modelo de
programación relacional coherente independiente del origen de datos. DataSet representa un conjunto completo
de datos que incluye tablas, restricciones y relaciones entre las tablas. Dado que DataSet es independiente del
origen de datos, DataSet puede incluir datos locales de la aplicación y datos de otros muchos orígenes. La
interacción con los orígenes de datos existentes se controla mediante el DataAdapter .
La propiedad SelectCommand de DataAdapter es un objeto Command que recupera datos del origen de datos. Las
propiedades InsertCommand , UpdateCommand y DeleteCommand de DataAdapter son objetos Command que permiten
administrar las actualizaciones de los datos en el origen de datos para reflejar las modificaciones efectuadas en los
datos de DataSet . Estas propiedades se tratan con más detalle en Actualización de orígenes de datos con
DataAdapters.
El método Fill de DataAdapter se usa para rellenar un objeto DataSet con los resultados del elemento
SelectCommand de DataAdapter . Fill toma como argumentos un elemento DataSet que se debe rellenar y un
objeto DataTable o el nombre del objeto DataTable que se debe rellenar con las filas que devuelve
SelectCommand .
NOTE
El uso de DataAdapter para recuperar la totalidad de una tabla lleva tiempo, en especial si la tabla incluye un gran número
de filas. Esto se debe a que el acceso a la base de datos, la localización y el procesamiento de los datos, y la posterior
transferencia de los mismos al cliente son procesos largos. La extracción de la tabla completa al cliente también bloquea
todas las filas en el servidor. Para mejorar el rendimiento, puede usar la cláusula WHERE para reducir en gran medida el
número de filas que se devuelven al cliente. También puede reducir la cantidad de datos que se devuelven al cliente si
enumera de forma explícita las columnas necesarias en la instrucción SELECT . Otra solución consiste en recuperar las filas
por lotes (por ejemplo varios cientos de filas de una vez) y recuperar solo el siguiente lote cuando el cliente haya finalizado
con el lote actual.
El método Fill utiliza el objeto DataReader de forma implícita para devolver los nombres y tipos de columna
que se usan para crear las tablas de DataSet , y los datos para rellenar las filas de las tablas en DataSet . Las tablas
y columnas solo se crean cuando no existen; en caso contrario, Fill utiliza el esquema existente de DataSet . Los
tipos de columna se crean como tipos de .NET Framework según las tablas de Asignacionesde tipos de datos de
ADO.NET . Las claves principales no se crean a DataAdapter menos que existan en el origen de datos y .
MissingSchemaAction se establece MissingSchemaAction en . AddWithKey . Si el método Fill encuentra que una
tabla tiene una clave principal, sobrescribe los datos de DataSet con los del origen de datos en las filas donde los
valores de columna de clave principal coinciden con los de la fila que devuelve el origen de datos. Si no se detecta
ninguna clave principal, los datos se agregan a las tablas de DataSet . Fill utiliza las asignaciones que pueden
DataSet existir al rellenar el (consulte DataAdapter DataTable y DataColumn Mappings).
NOTE
Si SelectCommand devuelve los resultados de OUTER JOIN, DataAdapter no establece un valor PrimaryKey para el
objeto DataTable resultante. Debe definir PrimaryKey para asegurarse de que las filas duplicadas se resuelven
correctamente. Para obtener más información, consulte Definición de claves principales.
En el ejemplo de código siguiente se crea una instancia de SqlDataAdapter que utiliza un objeto SqlConnection a la
base de datos Northwind de Microsoft SQL Server y se rellena un objeto DataTable en un DataSet con la lista de
clientes. La instrucción SQL y los argumentos SqlConnection pasados al constructor SqlDataAdapter se utilizan
para crear la propiedad SelectCommand del SqlDataAdapter.
Ejemplo
' Assumes that connection is a valid SqlConnection object.
Dim queryString As String = _
"SELECT CustomerID, CompanyName FROM dbo.Customers"
Dim adapter As SqlDataAdapter = New SqlDataAdapter( _
queryString, connection)
NOTE
El código que se muestra en este ejemplo no abre ni cierra explícitamente el objeto Connection . El método Fill abre de
forma implícita el objeto Connection que DataAdapter utiliza cuando encuentra que la conexión no está abierta todavía.
Si el método Fill ha abierto la conexión, también la cierra cuando el método Fill deja de utilizarla. Este hecho simplifica
el código cuando se trabaja con una operación única, como Fill o Update . Sin embargo, en el caso de que se estén
realizando varias operaciones que necesiten tener abierta una conexión, se puede mejorar el rendimiento de la aplicación
llamando explícitamente al método Open de Connection , realizando las operaciones en el origen de datos y, finalmente,
llamando al método Close de Connection . Es conveniente mantener abiertas las conexiones con el origen de datos el
menor tiempo posible para liberar recursos, de manera que estén disponibles para otras aplicaciones cliente.
custAdapter.Fill(customerOrders, "Customers");
ordAdapter.Fill(customerOrders, "Orders");
Capítulos de OLE DB
Se pueden usar conjuntos jerárquicos de filas, o capítulos (tipo DBTYPE_HCHAPTER de OLE DB y tipo adChapter de
ADO), para rellenar el contenido de DataSet . Cuando OleDbDataAdapter encuentra una columna que tiene un
capítulo durante una operación Fill , se crea un objeto DataTable para dicha columna y la tabla se rellena con
las columnas y filas del capítulo. Para asignar un nombre a la tabla creada para la columna con capítulo se usa
tanto el nombre de la tabla primaria como el de la columna con capítulo. El formato del nombre es
"nombreDeTablaPrimariaNombreDeColumnaConCapítulo". Si ya existe una tabla en DataSet que tenga el nombre
de la columna con capítulo, la tabla actual se rellena con los datos del capítulo. Si ninguna de las columnas de la
tabla existente coincide con una de las columnas del capítulo, se agrega una nueva columna a la tabla.
Antes de que las tablas de DataSet se rellenen con los datos de las columnas con capítulos, se crea una relación
entre las tablas primaria y secundaria del conjunto jerárquico de filas; para ello, se agrega una columna de tipo
entero a las tablas primaria y secundaria, se establece el valor de incremento automático para la columna de la
tabla primaria y se crea un objeto DataRelation usando las columnas agregadas de ambas tablas. Para asignar un
nombre a la relación se utilizan los nombres de la tabla primaria y de la columna con capítulo. El formato es
"nombreDeTablaPrimariaNombreDeColumnaConCapítulo".
Tenga en cuenta que la columna relacionada solo existe en DataSet . Las operaciones de relleno que se realicen
posteriormente desde el origen de datos pueden provocar que se agreguen nuevas filas a las tablas en lugar de
que se introduzcan los cambios en las filas existentes.
Tenga en cuenta además que, si se utiliza una sobrecarga de DataAdapter.Fill que acepte un objeto DataTable ,
solo se rellanará esa tabla. En este caso también se agrega a la tabla una columna de tipo entero y con incremento
automático, aunque no se crea ni rellena ninguna tabla secundaria, ni se crea ninguna relación.
En el ejemplo siguiente se utiliza el proveedor MSDataShape para generar un capítulo con la columna de pedidos
realizados por cada uno de los clientes de una lista. A continuación, se rellena un DataSet con los datos.
adapter.Fill(customers, "Customers")
End Using
using (OleDbConnection connection = new OleDbConnection("Provider=MSDataShape;Data Provider=SQLOLEDB;" +
"Data Source=(local);Integrated Security=SSPI;Initial Catalog=northwind"))
{
OleDbDataAdapter adapter = new OleDbDataAdapter("SHAPE {SELECT CustomerID, CompanyName FROM Customers} " +
"APPEND ({SELECT CustomerID, OrderID FROM Orders} AS Orders " +
"RELATE CustomerID TO CustomerID)", connection);
Una vez completada la operación Fill , DataSet contiene dos tablas: Customers y CustomersOrders , donde
CustomersOrders representa la columna con capítulo. Se agrega una columna adicional denominada Orders a la
tabla Customers , y una columna adicional denominada CustomersOrders a la tabla CustomersOrders . Se establece
el valor de incremento automático para la columna Orders de la tabla Customers . Se crea también una relación
DataRelation , CustomersOrders , utilizando las columnas que se han agregado a las tablas, siendo Customers la
tabla primaria. Las siguientes tablas muestran algunos ejemplos de los resultados.
Nombre de tabla: Customers
C USTO M ERID C O M PA N Y N A M E O RDERS
ALFKI 10643 0
ALFKI 10692 0
ANATR 10308 1
ANATR 10625 1
Consulte también
Objetos DataAdapter y DataReader
Asignaciones de tipos de datos en ADO.NET
Modificación de datos con un objeto DbDataAdapter
Conjuntos de resultados activos múltiples (MARS)
Información general de ADO.NET
Parámetros de DataAdapter
21/03/2020 • 12 minutes to read • Edit Online
DbDataAdapter tiene cuatro propiedades que se utilizan para recuperar y actualizar datos en el origen de datos: la
propiedad SelectCommand devuelve datos del origen de datos y las propiedades InsertCommand,
UpdateCommand y DeleteCommand se utilizan para administrar los cambios en el origen de datos. La propiedad
SelectCommand debe establecerse antes de llamar al método Fill de DataAdapter . Las propiedades
InsertCommand , UpdateCommand o DeleteCommand se deben establecer antes llamar al método Update de
DataAdapter , en función de las modificaciones realizadas en los datos en DataTable. Por ejemplo, si se han
agregado filas, se debe establecer InsertCommand antes de llamar a Update . Cuando Update procesa una fila
insertada, actualizada o eliminada, DataAdapter utiliza la propiedad Command que corresponde a la acción en
cuestión. La información actual relacionada con la fila modificada se pasa al objeto Command a través de la
colección Parameters .
Cuando se actualiza una fila en el origen de datos, se llama a la instrucción UPDATE, que usa un identificador único
para identificar la fila de la tabla que se va a actualizar. El identificador único suele ser el valor del campo de clave
principal. La instrucción UPDATE utiliza parámetros que contienen el identificador único y las columnas y valores
que se van a actualizar, como muestra la siguiente instrucción Transact-SQL.
NOTE
La sintaxis de los marcadores de posición de parámetros depende del origen de datos. En este ejemplo se muestran
marcadores de posición para un origen de datos de SQL Server. Utilice signos de interrogación de cierre (?) como
marcadores de posición de para los parámetros System.Data.OleDb y System.Data.Odbc.
En este ejemplo de CompanyName Visual Basic, el @CompanyName campo se actualiza CustomerID con el valor
@CustomerID del parámetro para la fila donde es igual al valor del parámetro. Los parámetros recuperan
información SourceColumn de la SqlParameter fila modificada mediante la propiedad del objeto. A continuación
se muestran los parámetros del ejemplo anterior de la instrucción UPDATE. En el código se parte de que el
adapter de la variable representa a un objeto SqlDataAdapter válido.
adapter.Parameters.Add( _
"@CompanyName", SqlDbType.NChar, 15, "CompanyName")
Dim parameter As SqlParameter = _
adapter.UpdateCommand.Parameters.Add("@CustomerID", _
SqlDbType.NChar, 5, "CustomerID")
parameter.SourceVersion = DataRowVersion.Original
El método Add de la colección Parameters toma el nombre del parámetro, el tipo de datos, el tamaño (si
corresponde al tipo) y el nombre de la propiedad SourceColumn de DataTable . Tenga en cuenta que
SourceVersion del parámetro @CustomerID se establece en Original . De esta forma se garantiza que la fila
existente en el origen de datos se actualice cuando el valor de la columna o columnas identificadas haya cambiado
en la fila DataRow modificada. En ese caso, el valor de la fila Original coincidiría con el valor actual en el origen
de datos y el valor de la fila Current contendría el valor actualizado. No se asigna ningún valor a SourceVersion
para el parámetro @CompanyName , por lo que se utiliza el valor predeterminado, el de la fila Current .
NOTE
Para las Fill operaciones DataAdapter del Get DataReader , el tipo de .NET Framework se deduce del tipo devuelto
por el proveedor de datos de .NET Framework. Los tipos de .NET Framework deducidos y los métodos de descriptor de
acceso para los tipos de datos de Microsoft SQL Server, OLE DB y ODBC se describen en Asignacionesde tipos de datos en
ADO.NET .
Parameter.SourceColumn, Parameter.SourceVersion
SourceColumn y SourceVersion se pueden pasar como argumentos al constructor Parameter , o también se
pueden establecer como propiedades de un Parameter existente. SourceColumn es el nombre de DataColumn de
DataRow en la que se recupera el valor de Parameter . SourceVersion especifica la versión de DataRow que utiliza
DataAdapter para recuperar el valor.
En la tabla siguiente se muestran los valores de la enumeración DataRowVersion disponibles para su uso con
SourceVersion .
adapter.UpdateCommand.Parameters.Add("@CustomerID",
SqlDbType.Char, 5, "CustomerID");
adapter.UpdateCommand.Parameters.Add("@CompanyName",
SqlDbType.VarChar, 40, "CompanyName");
adapter.UpdateCommand.Parameters.Add("@oldCustomerID",
SqlDbType.Char, 5, "CustomerID").SourceVersion =
DataRowVersion.Original;
adapter.DeleteCommand.Parameters.Add("@CustomerID",
SqlDbType.Char, 5, "CustomerID").SourceVersion =
DataRowVersion.Original;
return adapter;
}
Public Function CreateSqlDataAdapter( _
ByVal connection As SqlConnection) As SqlDataAdapter
adapter.UpdateCommand.Parameters.Add("@CustomerID", _
SqlDbType.Char, 5, "CustomerID")
adapter.UpdateCommand.Parameters.Add("@CompanyName", _
SqlDbType.VarChar, 40, "CompanyName")
adapter.UpdateCommand.Parameters.Add("@oldCustomerID", _
SqlDbType.Char, 5, "CustomerID").SourceVersion = _
DataRowVersion.Original
adapter.DeleteCommand.Parameters.Add("@CustomerID", _
SqlDbType.Char, 5, "CustomerID").SourceVersion = _
DataRowVersion.Original
Return adapter
End Function
Las instrucciones de consulta con parámetros definen qué parámetros de entrada y de salida se deben crear. Para
crear un parámetro, se utiliza el método Parameters.Add o el constructor Parameter con el fin de especificar el
nombre de columna, tipo de datos y tamaño. En el caso de tipos de datos intrínsecos, como Integer , no es
necesario incluir el tamaño, aunque se puede especificar el tamaño predeterminado.
En el ejemplo de código siguiente se crean los parámetros para una instrucción SQL y, a continuación, se llena un
DataSet .
Ejemplo de OleDb
' Assumes that connection is a valid OleDbConnection object.
Dim adapter As OleDbDataAdapter = New OleDbDataAdapter
Parámetros Odbc
' Assumes that connection is a valid OdbcConnection object.
Dim adapter As OdbcDataAdapter = New OdbcDataAdapter
NOTE
Si no se proporciona un nombre de parámetro para un parámetro, el parámetro recibe un nombre predeterminado
incremental de ParámetroN , empezando por "Parameter1". Se recomienda evitar la convención de nomenclatura
ParámetroN al proporcionar un nombre de parámetro, ya que el nombre que proporcione podría entrar en conflicto con un
nombre de parámetro predeterminado existente en el ParameterCollection archivo . Si el nombre proporcionado ya
existe, se inicia una excepción.
Consulte también
Objetos DataAdapter y DataReader
Comandos y parámetros
Actualizar orígenes de datos con objetos DataAdapter
Modificación de datos con procedimientos almacenados
Asignaciones de tipos de datos en ADO.NET
Información general de ADO.NET
Agregar restricciones existentes a un conjunto de
datos
23/10/2019 • 5 minutes to read • Edit Online
El método Fill de DataAdapter rellena una DataSet solo con las columnas y filas de la tabla de un origen de datos;
Aunque el origen de datos suele establecer restricciones, el método Fill no agrega esta información de esquema al
conjunto de datos de forma predeterminada. Para rellenar un conjunto de datos con información de restricciones
PRIMARY KEY de un origen de datos, puede llamar al método FillSchema de DataAdapter o establecer la
propiedad MissingSchemaAction de DataAdapter . para que el método sea AddWithKey antes de llamar a
Fill . Esto garantizará que las restricciones PRIMARY KEY del conjunto de datos reflejen las del origen de datos. La
información de restricción de clave externa no se incluye y se debe crear explícitamente, como se muestra en
restricciones de DataTable.
Agregar información de esquema a un conjunto de datos antes de rellenarlo con datos garantiza que las
restricciones PRIMARY KEY se incluyen con los objetos DataTable del conjunto de datos. Como resultado, cuando
se realizan llamadas adicionales para rellenar el conjunto de datos, la información de la columna de clave
principal se utiliza para hacer coincidir las nuevas filas del origen de datos con las filas actuales de cada DataTable ,
y los datos actuales de las tablas se sobrescriben con los datos del origen de datos. Sin la información del esquema,
las nuevas filas del origen de datos se anexan al conjunto de datos, lo que da lugar a filas duplicadas.
NOTE
Si una columna de un origen de datos se identifica como de incremento automático, el método FillSchema o el método Fill
con el MissingSchemaAction de AddWithKey , crea un DataColumn con una propiedad AutoIncrement . establezca en
true . Sin embargo, tendrá que establecer los valores de AutoIncrementStep y AutoIncrementSeed . Para obtener más
información acerca de las columnas de incremento automático, vea crear columnas de incrementoautomático.
En el ejemplo de código siguiente se muestra cómo agregar información de esquema a un conjunto de datos
mediante la propiedad MissingSchemaAction. AddWithKey del método Fill :
Dim custDataSet As New DataSet()
custAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
custAdapter.Fill(custDataSet, "Customers")
custAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
custAdapter.Fill(custDataSet, "Customers");
NOTE
Si se llama al método FillSchema del objeto OleDbDataAdapter para un comando que devuelve varios conjuntos de
resultados, solo se devuelve la información del esquema del primer conjunto de resultados. Al devolver información de
esquema para varios conjuntos de resultados mediante OleDbDataAdapter , se recomienda especificar el
MissingSchemaAction de AddWithKey y obtener la información del esquema al llamar al método Fill . forma.
Vea también
Objetos DataAdapter y DataReader
Objetos DataSet, DataTable y DataView
Recuperar y modificar datos en ADO.NET
Información general sobre ADO.NET
Correspondencias de DataTable y DataColumn en un
objeto DataAdapter
21/03/2020 • 6 minutes to read • Edit Online
workAdapter.TableMappings.Add("AuthorsMapping", "Authors")
workAdapter.TableMappings.Add("AuthorsMapping", "Authors");
Un DataTableMapping le permite usar nombres de columna en un DataTable que son diferentes de los de la
base de datos. El DataAdapter usa la asignación para que coincida con las columnas cuando se actualiza la tabla.
Si no especifica un TableName o un DataTableMapping nombre al llamar a la Fill o Update método de la
DataAdapter , el DataAdapter busca un DataTableMapping denominado "Table". Si ese DataTableMapping
no existe, el TableName de la DataTable es "Table". Puede especificar un valor predeterminado
DataTableMapping mediante la creación de un DataTableMapping con el nombre de "Table".
En el ejemplo de código siguiente System.Data.Common se crea un DataTableMapping (desde el espacio de
nombres) y lo convierte en la asignación predeterminada para el DataAdapter especificado nombrándolo "Table".
A continuación, el ejemplo asigna las columnas de la primera tabla del resultado de la consulta (la tabla
Customers de DataSetla base de datos Nor thwind) a un conjunto de nombres más fáciles de usar en la tabla
Nor thwind Customers del archivo . En las columnas que no se asignan se usa el nombre de la columna en el
origen de datos.
adapter.Fill(custDS)
DataTableMapping mapping =
adapter.TableMappings.Add("Table", "NorthwindCustomers");
mapping.ColumnMappings.Add("CompanyName", "Company");
mapping.ColumnMappings.Add("ContactName", "Contact");
mapping.ColumnMappings.Add("PostalCode", "ZIPCode");
adapter.Fill(custDS);
En situaciones más avanzadas, puede decidir que desea que el mismo DataAdapter admita la carga de tablas
diferentes con asignaciones diferentes. Para ello, simplemente agregue objetos DataTableMapping adicionales.
Cuando el Fill método se pasa una instancia de un DataSet y un DataTableMapping nombre, si existe una
asignación con ese nombre se utiliza; de lo contrario, se utiliza un DataTable con ese nombre.
En los ejemplos siguientes se crea un DataTableMapping con un nombre de Customers y un dataTable
nombre de BizTalkSchema . A continuación, el ejemplo asigna las filas devueltas por la instrucción SELECT a
BizTalkSchema DataTable .
adapter.Fill(custDS, "Customers")
ITableMapping mapping =
adapter.TableMappings.Add("Customers", "BizTalkSchema");
mapping.ColumnMappings.Add("CustomerID", "ClientID");
mapping.ColumnMappings.Add("CompanyName", "ClientName");
mapping.ColumnMappings.Add("ContactName", "Contact");
mapping.ColumnMappings.Add("PostalCode", "ZIP");
adapter.Fill(custDS, "Customers");
NOTE
Si no se proporciona un nombre de columna de origen en una asignación de columnas o no se identifica un nombre de tabla
de origen en una asignación de tablas, se generan nombres predeterminados de forma automática. Si no se proporciona
ninguna columna de origen para una asignación de columnas, la asignación de columnas recibe un nombre predeterminado
incremental de SourceColumn N, empezando por SourceColumn1 . Si no se proporciona ningún nombre de tabla de
origen para una asignación de tabla, la asignación de tabla recibe un nombre predeterminado incremental de SourceTable
N, empezando por SourceTable1 .
NOTE
Se recomienda evitar la convención de nomenclatura de SourceColumn N para una asignación de columnas o
SourceTable N para una asignación de tabla, ya que el nombre que proporcione puede entrar en conflicto con un nombre
de asignación de columna predeterminado existente en ColumnMappingCollection o nombre de asignación de tabla en
DataTableMappingCollection . Si el nombre proporcionado ya existe, se iniciará una excepción.
adapter.Fill(customersDataSet, "Customers")
adapter.Fill(customersDataSet, "Customers");
Se crean dos tablas en el conjunto de datos : Clientes y clientes1 . Puede utilizar asignaciones de tablas para
asegurarse de que la segunda tabla se denomina Pedidos en lugar de Customers1 . Para ello, asigne la tabla de
origen de Customers1 a la tabla DataSet Orders , como se muestra en el ejemplo siguiente.
adapter.TableMappings.Add("Customers1", "Orders")
adapter.Fill(customersDataSet, "Customers")
adapter.TableMappings.Add("Customers1", "Orders");
adapter.Fill(customersDataSet, "Customers");
Consulte también
Objetos DataAdapter y DataReader
Recuperar y modificar datos en ADO.NET
Información general de ADO.NET
Paginar un resultado de consulta
21/03/2020 • 6 minutes to read • Edit Online
La paginación a través del resultado de una consulta es un proceso que consiste en devolver los resultados de una
consulta en subconjuntos menores de datos, o páginas. Se trata de una práctica frecuente para presentar los
resultados a un usuario en fragmentos pequeños y fáciles de administrar.
El DataAdapter proporciona un recurso para devolver solo una página de datos, a través de sobrecargas de la Fill
método. Sin embargo, esta podría no ser la mejor opción para paginar a DataTable DataSet través de resultados de
consultas grandes porque, aunque el DataAdapter rellena el destino o solo con los registros solicitados, los
recursos para devolver toda la consulta se siguen utilizando. Para devolver una página de datos a partir de un
origen de datos sin utilizar los recursos necesarios para devolver toda la consulta, hay que especificar otros
criterios adicionales para la consulta que reduzcan las filas devueltas a las filas únicamente necesarias.
Para usar el método Fill para devolver una página de datos, especifique un parámetro star tRecord para el primer
registro de la página de datos y un parámetro maxRecords para el número de registros de la página de datos.
En el ejemplo de código siguiente se muestra cómo utilizar el Fill método para devolver la primera página de un
resultado de consulta donde el tamaño de página es de cinco registros.
int currentIndex = 0;
int pageSize = 5;
En el ejemplo anterior, el DataSet solo se rellena con cinco registros, pero se devuelve toda la tabla Orders. Para
rellenar el DataSet con esos mismos cinco registros, pero solo devolver cinco registros, use las cláusulas TOP y
WHERE en la instrucción SQL, como en el ejemplo de código siguiente.
Dim pageSize As Integer = 5
int pageSize = 5;
Hay que tener en cuenta que, al paginar a través del resultado de una consulta de esta forma, hay que conservar el
identificador único por el que están ordenadas las filas con el fin de pasar el identificador único al comando con el
fin de devolver la siguiente página de registros, tal y como se muestra en el ejemplo de código siguiente.
string lastRecord =
dataSet.Tables["Orders"].Rows[pageSize - 1]["OrderID"].ToString();
Para devolver la página siguiente de registros mediante la sobrecarga del método Fill que toma los parámetros
star tRecord y maxRecords, incremente el índice de registros actual por el tamaño de página y rellene la tabla.
Recuerde que el servidor de base de datos devuelve todos los resultados de la consulta aunque solo se agregue
una página de registros al conjunto de datos . En el siguiente ejemplo de código se vacía el contenido de las filas de
la tabla antes de rellenarse con la siguiente página de datos. Quizás se desee conservar un cierto número de filas
devueltas en una caché local para reducir los viajes al servidor de bases de datos.
dataSet.Tables("Orders").Rows.Clear()
currentIndex += pageSize;
dataSet.Tables["Orders"].Rows.Clear();
Para devolver la siguiente página de registros sin que el servidor de bases de datos tenga que devolver toda la
consulta, hay que especificar criterios restrictivos en la instrucción SELECT. Como el ejemplo anterior conservaba el
último registro devuelto, es posible utilizarlo en la cláusula WHERE con el fin de especificar un punto de partida
para la consulta, como se muestra en el ejemplo de código siguiente.
orderSQL = "SELECT TOP " & pageSize & _
" * FROM Orders WHERE OrderID > " & lastRecord & " ORDER BY OrderID"
adapter.SelectCommand.CommandText = orderSQL
dataSet.Tables("Orders").Rows.Clear()
adapter.Fill(dataSet, "Orders")
dataSet.Tables["Orders"].Rows.Clear();
adapter.Fill(dataSet, "Orders");
Consulte también
Objetos DataAdapter y DataReader
Información general de ADO.NET
Actualizar orígenes de datos con objetos
DataAdapter
23/10/2019 • 22 minutes to read • Edit Online
El método Update de DataAdapter se llama para reflejar en el origen de datos todos los cambios efectuados en
DataSet. El método Update , al igual que el método Fill , acepta como argumentos una instancia de DataSet y,
de forma opcional, un objeto DataTable o un nombre de DataTable . La instancia de DataSet es el DataSet que
contiene los cambios efectuados, y DataTable identifica la tabla desde la que se pueden recuperar esos cambios.
Si no se especifica DataTable , se utiliza el primer DataTable de DataSet .
Al llamar al método Update , DataAdapter analiza los cambios efectuados y ejecuta el comando apropiado
(INSERT, UPDATE o DELETE). Cuando DataAdapter encuentra un cambio en DataRow, utiliza los comandos
InsertCommand, UpdateCommand o DeleteCommand para reflejarlo. De esta forma, se obtiene el máximo
rendimiento de la aplicación de ADO.NET al especificar la sintaxis del comando en la fase de diseño y utilizar,
siempre que es posible, procedimientos almacenados. Antes de llamar a Update deben establecerse de forma
explícita los comandos. Si se llama a Update y el comando correspondiente a una actualización determinada no
existe (por ejemplo, no hay un comando DeleteCommand para las filas eliminadas), se inicia una excepción.
NOTE
Si está utilizando procedimientos almacenados de SQL Server para editar o eliminar datos con DataAdapter , asegúrese
de que no utiliza SET NOCOUNT ON en la definición del procedimiento almacenado. Esto hace que el recuento de filas
afectadas vuelva a cero, lo que DataAdapter interpreta como un conflicto de simultaneidad. En este caso, se iniciará una
DBConcurrencyException.
Se pueden usar los parámetros de comando para especificar los valores de entrada y salida de una instrucción
SQL o un procedimiento almacenado para cada fila modificada en DataSet . Para obtener más información, vea
DataAdapter Parameters.
NOTE
Es importante comprender la diferencia entre eliminar una fila de una DataTable y quitar la fila. Al llamar al método
Remove o RemoveAt , la fila se quita inmediatamente. Cualquier fila correspondiente en el origen de datos back end no se
verá afectada si a continuación se pasa DataTable o DataSet a DataAdapter y se llama a Update . Al utilizar el
método Delete , la fila permanece en DataTable y se marca para eliminación. Si a continuación se pasa DataTable o
DataSet a DataAdapter y se llama a Update , la fila correspondiente en el origen de datos back end se elimina.
Si DataTable está asignada a una única base de datos o se ha generado a partir de ella, puede utilizar el objeto
DbCommandBuilder para generar automáticamente los objetos DeleteCommand , InsertCommand y UpdateCommand
de DataAdapter . Para obtener más información, vea generar comandos con objetos CommandBuilder.
None Se pasan por alto todos los parámetros de salida y las filas
del conjunto de resultados devuelto.
El método Update vuelve a resolver los cambios en el origen de datos; sin embargo, puede que otros clientes
hayan modificado datos en el origen de datos desde la última vez que se llenó DataSet . Para actualizar DataSet
con datos actuales, utilice el DataAdapter y el método Fill . De esta forma se agregan las filas nuevas a la tabla
y se actualiza la información en las filas ya existentes. El método Fill determina si se va a agregar una nueva
fila o si se va a actualizar una fila existente mediante el examen de los valores de clave principal de las filas de
DataSet y las filas devueltas por SelectCommand . Si el método Fill encuentra un valor de clave principal de una
fila de DataSet que coincide con un valor de clave principal de una fila de los resultados devueltos por
SelectCommand , éste actualiza la fila existente con la información de la fila devuelta por SelectCommand y establece
el RowState de la fila existente en Unchanged . Si una fila devuelta por SelectCommand tiene un valor de clave
principal que no coincide con ninguno de los valores de clave principal de las filas de DataSet , el método Fill
agrega una nueva fila con un RowState de Unchanged .
NOTE
Si SelectCommand devuelve los resultados de una combinación externa (OUTER JOIN), DataAdapter no establecerá un
valor PrimaryKey para la tabla DataTable resultante. Debe definir PrimaryKey para asegurarse de que las filas
duplicadas se resuelven correctamente. Para obtener más información, vea definir claves principales.
Para controlar las excepciones que se pueden producir al Update llamar al método, puede utilizar RowUpdated el
evento para responder a los errores de actualización de fila a medida que se producen (vea controlar eventos
DataAdapter) true , o puede establecer DataAdapter.ContinueUpdateOnError en antes de llamar Update a y
responder a la información de error almacenada RowError en la propiedad de una fila determinada cuando se
completa la actualización (vea la información de error de fila).
NOTE
Llamar AcceptChanges a DataRow DataRow Current en DataSet , DataTable o Original hará que todos los
valores de se sobrescriban con los valores de. DataRow Si se han modificado los valores de campo que identifican de
forma única a una fila, los valores AcceptChanges dejarán de coincidir con los valores del origen de datos después de
llamar a Original . Se llama automáticamente a AcceptChanges para cada fila durante una llamada al método Update
de DataAdapter . Puede conservar los valores originales durante una llamada al método Update estableciendo primero la
propiedad AcceptChangesDuringUpdate de DataAdapter en false o creando un controlador de eventos para el evento
RowUpdated y estableciendo Status en SkipCurrentRow. Para obtener más información, vea combinar el contenido de un
conjunto de datos y controlar eventos DataAdapter.
Ejemplo
En los siguientes ejemplos se muestra cómo realizar actualizaciones de las filas modificadas estableciendo
UpdateCommand explícitamente DataAdapter el valor de Update y llamando a su método. Observe cómo el
parámetro especificado en la cláusula WHERE de la instrucción UPDATE tiene el valor adecuado para usar el valor
Original de SourceColumn . Este hecho es muy importante ya que el valor Current puede haber sido
modificado de forma que ya no coincida con el valor del origen de datos. El valor Original es el que se usó para
rellenar la tabla DataTable a partir del origen de datos.
dataAdpater.UpdateCommand.Parameters.Add(
"@CategoryName", SqlDbType.NVarChar, 15, "CategoryName");
dataAdpater.Update(categoryTable);
adapter.UpdateCommand.Parameters.Add( _
"@CategoryName", SqlDbType.NVarChar, 15, "CategoryName")
adapter.Update(categoryTable)
Columnas AutoIncrement
Si las tablas del origen de datos tienen columnas con incremento automático, puede rellenar las columnas de
DataSet devolviendo el valor de incremento automático como un parámetro de salida de un procedimiento
almacenado y asignándolo a una columna de la tabla, o devolviendo el valor de incremento automático de la
primera fila de un conjunto de resultados devuelto por un procedimiento almacenado o una instrucción SQL, o
mediante el evento RowUpdated de DataAdapter para ejecutar una instrucción SELECT adicional. Para obtener
más información y un ejemplo, vea recuperar valores de identidad o Autonumérico.
USE [master]
GO
GO
USE [MySchool]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Course]([CourseID] [nvarchar](10) NOT NULL,
[Year] [smallint] NOT NULL,
[Title] [nvarchar](100) NOT NULL,
[Credits] [int] NOT NULL,
[DepartmentID] [int] NOT NULL,
CONSTRAINT [PK_Course] PRIMARY KEY CLUSTERED
(
[CourseID] ASC,
[Year] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Department]([DepartmentID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Budget] [money] NOT NULL,
[StartDate] [datetime] NOT NULL,
[Administrator] [int] NULL,
CONSTRAINT [PK_Department] PRIMARY KEY CLUSTERED
(
[DepartmentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C1045', 2012,
N'Calculus', 4, 7)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C1061', 2012,
N'Physics', 4, 1)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C2021', 2012,
N'Composition', 3, 2)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C2042', 2012,
N'Literature', 4, 2)
ALTER TABLE [dbo].[Course] WITH CHECK ADD CONSTRAINT [FK_Course_Department] FOREIGN KEY([DepartmentID])
REFERENCES [dbo].[Department] ([DepartmentID])
GO
ALTER TABLE [dbo].[Course] CHECK CONSTRAINT [FK_Course_Department]
GO
C#y Visual Basic proyectos con este ejemplo de código se pueden encontrar en ejemplos de código para
desarrolladores.
using System;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using CSDataAdapterOperations.Properties;
namespace CSDataAdapterOperations.Properties {
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("Data Source=(local);Initial
Catalog=MySchool;Integrated Security=True")]
public string MySchoolConnectionString {
get {
return ((string)(this["MySchoolConnectionString"]));
}
}
}
}
class Program {
static void Main(string[] args) {
Settings settings = new Settings();
// Copy the data from the database. Get the table Department and Course from the database.
String selectString = @"SELECT [DepartmentID],[Name],[Budget],[StartDate],[Administrator]
FROM [MySchool].[dbo].[Department];
// Use DataTableMapping to map the source tables and the destination tables.
DataTableMapping[] tableMappings = {new DataTableMapping("Table", "Department"), new
DataTableMapping("Table1", "Course")};
CopyData(mySchool, settings.MySchoolConnectionString, selectCommand, tableMappings);
department.RejectChanges();
Console.WriteLine("After use the RejectChanges method in Department table to roll back the changes:");
ShowDataTable(department);
connection.Open();
adapter.Fill(dataSet);
}
}
}
// Roll back only one column or several columns data of the Course table by call ResetDataTable method.
private static void ResetCourse(DataTable table, String connectionString,
DataColumn[] primaryColumns, DataColumn[] resetColumns) {
table.PrimaryKey = primaryColumns;
// RejectChanges will roll back all changes made to the table since it was loaded, or the last time
AcceptChanges
// was called. When you copy from the database, you can lose all the data after calling RejectChanges
// was called. When you copy from the database, you can lose all the data after calling RejectChanges
// The ResetDataTable method rolls back one or more columns of data.
private static void ResetDataTable(DataTable table, String connectionString,
SqlCommand selectCommand) {
using (SqlConnection connection = new SqlConnection(connectionString)) {
selectCommand.Connection = connection;
connection.Open();
adapter.Fill(table);
}
}
}
connection.Open();
adapter.Update(table);
Vea también
Objetos DataAdapter y DataReader
Estados y versiones de filas
AcceptChange y RejectChange
Combinar contenido de DataSet
Recuperación de valores autonuméricos y de identidad
Información general sobre ADO.NET
Controlar eventos de DataAdapter
21/03/2020 • 10 minutes to read • Edit Online
DataAdapter de ADO.NET expone tres eventos que se pueden utilizar para responder a los cambios efectuados
en los datos en el origen. En la siguiente tabla se muestran los eventos de DataAdapter .
RowUpdating y RowUpdated
El evento RowUpdating se activa antes de que se produzca la actualización de una fila del DataSet en el origen de
datos. El evento RowUpdated se activa después de que se produzca la actualización de una fila del DataSet en el
origen de datos. Por lo tanto, puede utilizar RowUpdating para modificar el comportamiento de la actualización
antes de que tenga lugar, proporcionar un control adicional del proceso durante la actualización, conservar una
referencia a la fila actualizada, cancelar la actualización actual y programarla como parte de un proceso por lotes
que se ejecutará después, entre otras acciones. RowUpdated es útil para reaccionar cuando se producen errores y
excepciones durante la actualización. Puede agregar información de errores al DataSet , así como
procedimientos de reintento, etcétera.
Los argumentos RowUpdatingEventArgs y RowUpdatedEventArgs que se pasan a los eventos RowUpdating y
RowUpdated incluyen lo siguiente: una propiedad Command que hace referencia al objeto Command que se está
utilizando para realizar la actualización; una propiedad Row que hace referencia al objeto DataRow que contiene
la información actualizada; una propiedad StatementType para el tipo de actualización que se está llevando a
cabo; el valor de TableMapping , si es pertinente y el valor de Status de la operación.
Puede utilizar la propiedad Status para determinar si se ha producido o no un error durante la operación y, si lo
desea, controlar las acciones que se emprenden en las filas actuales y las resultantes de la operación. Cuando se
produce el evento, la propiedad Status toma el valor Continue o ErrorsOccurred . En la tabla siguiente se
muestran los valores que se pueden asignar a la propiedad Status para controlar las acciones posteriores en el
proceso de actualización.
Al establecer a la propiedad Status en el valor ErrorsOccurred se inicia una excepción. Puede controlar qué
excepciones se inician si establece la propiedad Errors en la excepción que desee. El uso de un valor distinto
para la propiedad Status evita que se inicie una excepción.
También puede utilizar la propiedad ContinueUpdateOnError para controlar los errores producidos en las filas
actualizadas. Cuando DataAdapter.ContinueUpdateOnError tiene el valor true y la actualización de una fila inicia
una excepción, el texto de la excepción se coloca en la información RowError de la fila en cuestión y el proceso
continúa sin que se inicie una excepción. De esta forma, puede responder a los errores cuando se complete el
proceso Update , a diferencia del evento RowUpdated , que permite responder a los errores cuando se detectan.
En el ejemplo de código siguiente se muestra cómo se pueden agregar y quitar controladores de eventos. El
controlador de eventos RowUpdating mantiene un registro de todos los registros eliminados y una marca de
tiempo asociada a cada uno de ellos. El RowUpdated controlador de eventos agrega RowError información de
error DataSet a la propiedad de la fila en ContinueUpdateOnError = true el , suprime la excepción y continúa el
procesamiento (reflejando el comportamiento de ).
' Set DataAdapter command properties, fill DataSet, and modify DataSet.
custAdapter.Update(custDS, "Customers")
// Add handlers.
custAdapter.RowUpdating += new SqlRowUpdatingEventHandler(OnRowUpdating);
custAdapter.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated);
custAdapter.Update(custDS, "Customers");
// Remove handlers.
custAdapter.RowUpdating -= new SqlRowUpdatingEventHandler(OnRowUpdating);
custAdapter.RowUpdated -= new SqlRowUpdatedEventHandler(OnRowUpdated);
FillError
Cuando se produce un error durante una operación DataAdapter , el objeto FillError provoca el evento Fill .
Este tipo de error suele producirse si al convertir los datos de la fila que se agrega a un tipo de .NET Framework
se produce una pérdida de precisión.
Si el error se produce durante una operación Fill , la fila actual no se agrega al objeto DataTable . El evento
FillError permite resolver el error y agregar la fila o bien pasar por alto la fila excluida y continuar con la
operación Fill .
El objeto FillErrorEventArgs que se pasa al evento FillError puede contener varias propiedades que permiten
reaccionar en caso de errores y resolverlos. En la tabla siguiente se muestran las propiedades del objeto
FillErrorEventArgs .
En el siguiente ejemplo de código se agrega un controlador para el evento FillError del objeto DataAdapter .
En el código del evento FillError , el ejemplo determina si hay una posible pérdida de precisión y ofrece la
posibilidad de reaccionar ante la excepción.
La compatibilidad con las operaciones por lotes en ADO.NET permite que un DataAdapter agrupe operaciones
INSERT, UPDATE y DELETE desde un DataSet o una DataTable al servidor, en lugar de enviar las operaciones de una
en una. La reducción del número de viajes de ida y vuelta (round trip) al servidor tiene como resultado una mejora
considerable del rendimiento. Las actualizaciones por lotes son compatibles con los proveedores de datos de .NET
para SQL Server (System.Data.SqlClient) y Oracle (System.Data.OracleClient).
Al actualizar una base de datos con modificaciones de un DataSet en versiones anteriores de ADO.NET, el método
Update de un DataAdapter realizaba actualizaciones de las filas de la base de datos de una en una. A medida que
recorría las filas de la DataTable especificada, examinaba cada DataRow para ver si se había modificado. Si se había
modificado la fila, llamaba al UpdateCommand , InsertCommand o DeleteCommand apropiado, en función del valor de
propiedad RowState de la fila. Cada actualización de una fila implicaba un viaje de ida y vuelta (round trip) a la base
de datos.
A partir de ADO.NET 2.0, DbDataAdapter expone una propiedad UpdateBatchSize. Si se establece el
UpdateBatchSize en un valor entero positivo, se producen actualizaciones en la base de datos que se envían como
lotes del tamaño especificado. Por ejemplo, si se establece el UpdateBatchSize en 10, se agrupan 10 instrucciones
separadas y se envían en un único lote. Si se establece el UpdateBatchSize en 0, el DataAdapter utilizará el mayor
tamaño de lote admitido por el servidor. Si se establece el valor en 1, se deshabilitan las actualizaciones por lotes y
las filas se envían de una en una.
Si se ejecuta un lote demasiado grande, el rendimiento podría verse afectado. Por tanto, es conveniente realizar
pruebas a fin de determinar el valor óptimo del tamaño del lote antes de implementar la aplicación.
// Create a SqlDataAdapter.
SqlDataAdapter adapter = new SqlDataAdapter();
Consulte también
Objetos DataAdapter y DataReader
Actualizar orígenes de datos con objetos DataAdapter
Controlar eventos de DataAdapter
Información general de ADO.NET
Transacciones y simultaneidad
23/10/2019 • 2 minutes to read • Edit Online
Una transacción consiste en un comando único o en un grupo de comandos que se ejecutan como un paquete.
Las transacciones permiten combinar varias operaciones en una sola unidad de trabajo. Si en un punto de la
transacción se produjera un error, todas las actualizaciones podrían revertirse y devolverse al estado que tenían
antes de la transacción.
Una transacción debe ajustarse a las propiedades ACID (atomicidad, coherencia, aislamiento y durabilidad) para
poder garantizar la coherencia de datos. La mayoría de los sistemas de bases de datos relacionales, como
Microsoft SQL Server, admiten transacciones, al proporcionar funciones de bloqueo, registro y administración
de transacciones cada vez que una aplicación cliente realiza una operación de actualización, inserción o
eliminación.
NOTE
Las transacciones que requieren varios recursos pueden reducir la simultaneidad si la duración del bloqueo es demasiado
larga. Por ello, haga la transacción lo más corta posible.
Las transacciones explícitas en procedimientos almacenados suelen dar mejores resultados cuando una
transacción implica el uso de varias tablas en la misma base de datos o servidor. Se pueden crear transacciones
en procedimientos almacenados de SQL Server mediante las instrucciones BEGIN TRANSACTION ,
COMMIT TRANSACTION o ROLLBACK TRANSACTION de Transact-SQL. Para obtener más información, vea los Libros en
pantalla de SQL Server.
Las transacciones que implican diferentes administradores de recursos, como una transacción entre SQL Server
y Oracle, requieren una transacción distribuida.
En esta sección
Transacciones locales
Muestra cómo realizar transacciones en una base de datos.
Transacciones distribuidas
Describe cómo realizar transacciones distribuidas en ADO.NET.
Integración de System.Transactions con SQL Server
Describe System.Transactions la integración con SQL Server para trabajar con transacciones distribuidas.
Simultaneidad optimista
Describe la simultaneidad optimista y pesimista, y cómo puede probar las infracciones de simultaneidad.
Vea también
Principios de la transacción
Conexión a un origen de datos
Comandos y parámetros
Objetos DataAdapter y DataReader
Objetos DbProviderFactory
Información general sobre ADO.NET
Transacciones locales
23/10/2019 • 6 minutes to read • Edit Online
Las transacciones de ADO.NET se usan cuando se desea enlazar varias tareas juntas para que se ejecuten como una
sola unidad de trabajo. Por ejemplo, imagine que una aplicación realiza dos tareas. Primero, actualiza una tabla con
información de pedidos. Luego, actualiza una tabla que contiene la información de inventario, cargando en cuenta
los elementos pedidos. Si se produce un error en cualquiera de las tareas, se revierten ambas.
NOTE
Las transacciones son más eficaces cuando se realizan en el servidor. Si trabaja con una base de datos de SQL Server que
hace uso masivo de transacciones explícitas, debería estudiar la posibilidad de escribirlas como procedimientos almacenados
mediante la instrucción BEGIN TRANSACTION de Transact-SQL.
NOTE
El método EnlistDistributedTransaction no se debe emplear en transacciones locales.
El ámbito de la transacción está limitado a la conexión. En el siguiente ejemplo se realiza una transacción explícita
que consta de por dos comandos independientes en el bloque try . Los comandos ejecutan instrucciones INSERT
en la tabla Production. ScrapReason de la base de datos de ejemplo AdventureWorks SQL Server, que se confirman
si no se inicia ninguna excepción. El código del bloque catch revierte la transacción si se produce una excepción.
Si la transacción se anula o la conexión se cierra antes de que se haya completado la transacción, ésta se revierte
automáticamente.
Ejemplo
Para llevar a cabo una transacción, siga estos pasos.
1. Llame al método BeginTransaction del objeto SqlConnection para marcar el comienzo de la transacción. El
método BeginTransaction devuelve una referencia a la transacción. Esta referencia se asigna a los objetos
SqlCommand que están inscritos en la transacción.
2. Asigne el objeto Transaction a la propiedad Transaction del objeto SqlCommand que se va a ejecutar. Si el
comando se ejecuta en una conexión con una transacción activa y el objeto Transaction no se ha asignado
a la propiedad Transaction del objeto Command , se inicia una excepción.
3. Ejecute los comandos necesarios.
4. Llame al método Commit del objeto SqlTransaction para completar la transacción, o al método Rollback para
finalizarla. Si la conexión se cierra o elimina antes de que se hayan ejecutado los métodos Commit o
Rollback, la transacción se revierte.
En el ejemplo de código siguiente se muestra la lógica transaccional mediante ADO.NET con Microsoft SQL Server.
try
{
// Execute two separate commands.
command.CommandText =
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')";
command.ExecuteNonQuery();
command.CommandText =
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')";
command.ExecuteNonQuery();
try
{
// Attempt to roll back the transaction.
sqlTran.Rollback();
}
catch (Exception exRollback)
{
// Throws an InvalidOperationException if the connection
// is closed or the transaction has already been rolled
// back on the server.
Console.WriteLine(exRollback.Message);
}
}
}
Using connection As New SqlConnection(connectionString)
connection.Open()
Try
' Execute two separate commands.
command.CommandText = _
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')"
command.ExecuteNonQuery()
command.CommandText = _
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')"
command.ExecuteNonQuery()
Catch ex As Exception
' Handle the exception if the transaction fails to commit.
Console.WriteLine(ex.Message)
Try
' Attempt to roll back the transaction.
sqlTran.Rollback()
Vea también
Transacciones y simultaneidad
Transacciones distribuidas
Integración de System.Transactions con SQL Server
Información general sobre ADO.NET
Transacciones distribuidas
23/10/2019 • 9 minutes to read • Edit Online
Entre otras cosas, una transacción es un conjunto de tareas relacionadas que se ejecutan correctamente
(confirman) o dan error (anulan) como una unidad. Una transacción distribuida es una transacción que afecta a
varios recursos. Para que una transacción distribuida se confirme, todos los participantes deben garantizar que los
cambios en los datos serán permanentes. Los cambios deben conservarse a pesar de bloqueos del sistema u otros
eventos imprevistos. Si alguno de los participantes no cumple esta garantía, toda la transacción da error y se
revertirán los cambios en los datos en el ámbito de la transacción.
NOTE
Si intenta confirmar o revertir una transacción al iniciar un DataReader mientras la transacción está activa, se produce una
excepción.
NOTE
El número máximo de transacciones distribuidas en las que puede participar una base de datos de Oracle a la vez se
establece de forma predeterminada en 10. Después de la décima transacción en una conexión a una base de datos de Oracle,
se inicia una excepción. Oracle no admite DDL en las transacciones distribuidas.
NOTE
Una vez que una conexión se inscribe explícitamente en una transacción, no se puede anular su inscripción ni inscribirse en
otra transacción hasta que finaliza la primera transacción.
Cau t i on
La versión 2.0 de .NET Framework introdujo System.Transactions un marco de transacciones al que se puede
tener acceso a través del espacio de nombres. Este marco de trabajo expone las transacciones de una manera que
está totalmente integrada en .NET Framework, incluida ADO.NET.
Además de las mejoras System.Transactions de programación, y ADO.NET pueden trabajar juntas para coordinar
optimizaciones cuando se trabaja con transacciones. Una transacción promovible es una transacción ligera (local)
que, en caso necesario, se puede promover automáticamente a una transacción completamente distribuida.
A partir de ADO.NET System.Data.SqlClient 2.0, admite transacciones promocionables cuando se trabaja con SQL
Server. Las transacciones promovibles no invocan la sobrecarga adicional de las transacciones distribuidas a
menos que sea necesario. Las transacciones promocionables son automáticas y no requieren intervención del
desarrollador.
Las transacciones promocionables solo están disponibles cuando se SqlClient usa el proveedor de datos de .NET
Framework para SQL Server ( ) con SQL Server.
NOTE
En un caso que no es de plena confianza, se requiere DistributedTransactionPermission cuando la transacción se promueve
al nivel de transacción distribuida.
Uso de TransactionScope
La clase TransactionScope crea un bloque de código transaccional dando de alta implícitamente las conexiones en
una transacción distribuida. Debe llamar al método Complete al final del bloque TransactionScope antes de
abandonarlo. Al salir del bloque se invoca el método Dispose . Si se ha producido una excepción que ocasiona
que el código salga del ámbito, la transacción se considera anulada.
Se recomienda el uso de un bloque using para asegurarse de que se llama a Dispose en el objeto
TransactionScope cuando se sale de dicho bloque. Si no se confirman ni revierten las transacciones pendientes, el
rendimiento puede verse seriamente afectado ya que el tiempo de espera predeterminado de TransactionScope
es un minuto. Si no utiliza una instrucción using , debe realizar todo el trabajo de un bloque Try y llamar
explícitamente al método Dispose del bloque Finally .
Si se produce una excepción en TransactionScope, la transacción se marca como incoherente y se abandona. Se
revertirá cuando se elimine el TransactionScope . Si no se produce ninguna excepción, las transacciones
participantes se confirman.
NOTE
La clase TransactionScope crea una transacción con IsolationLevel de Serializable de forma predeterminada.
Dependiendo de la aplicación, puede considerar la opción de reducir el nivel de aislamiento para evitar conflictos en ella.
NOTE
Se recomienda que solo realice actualizaciones, inserciones y eliminaciones en transacciones distribuidas, ya que consumen
una cantidad considerable de recursos de base de datos. Las instrucciones SELECT pueden bloquear los recursos de base de
datos de forma innecesaria y, en algunas situaciones, es posible que tengan que utilizarse transacciones para las selecciones.
Todo el trabajo que no sea de base de datos debe realizarse fuera del ámbito de la transacción, a menos que estén
implicados otros administradores de recursos de transacción. Aunque una excepción en el ámbito de la transacción impide
que se confirme la misma, la clase TransactionScope no deja revertir los cambios que haya realizado el código fuera del
ámbito de la propia transacción. Si es necesario realizar alguna acción cuando se revierta la transacción, deberá escribir su
propia implementación de la interfaz IEnlistmentNotification y darla de alta explícitamente en la transacción.
Ejemplo
Trabajar con System.Transactions requiere disponer de una referencia a System.Transactions.dll.
La siguiente función muestra cómo crear una transacción promocionada en dos instancias de SQL Server
diferentes, representadas por dos objetos SqlConnection diferentes, que se incluyen en un bloque
TransactionScope . El código crea el bloque TransactionScope con una instrucción using y abre la primera
conexión, que automáticamente se da de alta en TransactionScope. La transacción se da de alta inicialmente como
una transacción ligera, no como una transacción distribuida completa. La segunda conexión se inscribe en
TransactionScope únicamente si el comando de la primera conexión no produce una excepción. Cuando se abre la
segunda conexión, la transacción se promociona automáticamente a una transacción completamente distribuida.
Se invoca el método Complete , que confirma la transacción únicamente si no se han producido excepciones. Si
en algún punto del bloque TransactionScope se ha producido una excepción, no se llamará a Complete y, cuando
se elimine TransactionScope al final de su bloque using , se revertirá la transacción distribuida.
// This function takes arguments for the 2 connection strings and commands in order
// to create a transaction involving two SQL Servers. It returns a value > 0 if the
// transaction committed, 0 if the transaction rolled back. To test this code, you can
// connect to two different databases on the same server by altering the connection string,
// or to another RDBMS such as Oracle by altering the code in the connection2 code block.
static public int CreateTransactionScope(
string connectString1, string connectString2,
string commandText1, string commandText2)
{
// Initialize the return value to zero and create a StringWriter to display results.
int returnValue = 0;
System.IO.StringWriter writer = new System.IO.StringWriter();
// Display messages.
Console.WriteLine(writer.ToString());
return returnValue;
}
' This function takes arguments for the 2 connection strings and commands in order
' to create a transaction involving two SQL Servers. It returns a value > 0 if the
' transaction committed, 0 if the transaction rolled back. To test this code, you can
' connect to two different databases on the same server by altering the connection string,
' or to another RDBMS such as Oracle by altering the code in the connection2 code block.
Public Function CreateTransactionScope( _
ByVal connectString1 As String, ByVal connectString2 As String, _
ByVal commandText1 As String, ByVal commandText2 As String) As Integer
' Initialize the return value to zero and create a StringWriter to display results.
Dim returnValue As Integer = 0
Dim writer As System.IO.StringWriter = New System.IO.StringWriter
' Create the SqlCommand object and execute the first command.
Dim command1 As SqlCommand = New SqlCommand(commandText1, connection1)
returnValue = command1.ExecuteNonQuery()
writer.WriteLine("Rows to be affected by command1: {0}", returnValue)
' If you get here, this means that command1 succeeded. By nesting
' the Using block for connection2 inside that of connection1, you
' conserve server and network resources by opening connection2
' only when there is a chance that the transaction can commit.
Using connection2 As New SqlConnection(connectString2)
Using connection2 As New SqlConnection(connectString2)
Try
' The transaction is promoted to a full distributed
' transaction when connection2 is opened.
connection2.Open()
Catch ex As Exception
' Display information that command2 failed.
writer.WriteLine("returnValue for command2: {0}", returnValue)
writer.WriteLine("Exception Message2: {0}", ex.Message)
End Try
End Using
Catch ex As Exception
' Display information that command1 failed.
writer.WriteLine("returnValue for command1: {0}", returnValue)
writer.WriteLine("Exception Message1: {0}", ex.Message)
End Try
End Using
Return returnValue
End Function
Consulte también
Transacciones y simultaneidad
Información general de ADO.NET
Simultaneidad optimista
21/03/2020 • 16 minutes to read • Edit Online
En un entorno multiusuario existen dos modelos para actualizar datos en una base de datos: simultaneidad
optimista y simultaneidad pesimista. El objeto DataSet está diseñado para fomentar el uso de la simultaneidad
optimista en actividades cuya ejecución tiene una larga duración, como cuando se trabaja con interacción remota y
cuando los usuarios interactúan con datos.
La simultaneidad pesimista implica bloquear filas en el origen de datos para impedir que otros usuarios
modifiquen los datos de tal forma que el usuario actual resulte afectado. En un modelo pesimista, cuando un
usuario realiza una acción que hace que se aplique un bloqueo, otros usuarios no pueden realizar acciones que
entrarían en conflicto con el bloqueo hasta que el propietario del bloqueo lo libere. Este modelo se utiliza
principalmente en aquellos entornos en los que hay mucha contención de datos, de manera que el costo de
proteger los datos con bloqueos es menor que el costo de revertir transacciones si se producen conflictos de
simultaneidad.
Por tanto, en un modelo de simultaneidad pesimista, un usuario que actualiza una fila establece un bloqueo. Hasta
que el usuario no haya terminado la actualización y liberado el bloqueo, nadie más podrá modificar dicha fila. Por
este motivo, la simultaneidad pesimista resulta más adecuada cuando los tiempos de bloqueo son cortos, como
ocurre en el procesamiento de registros mediante programación. La simultaneidad pesimista no es una opción
escalable cuando los usuarios interactúan con los datos y hacen que los registros queden bloqueados durante
períodos de tiempo relativamente largos.
NOTE
Si necesita actualizar varias filas en una misma operación, entonces crear una transacción es una opción más escalable que
utilizar el bloqueo pesimista.
Por el contrario, los usuarios que utilizan la simultaneidad optimista no bloquean una fila cuando la leen. Cuando
un usuario desea actualizar una fila, la aplicación debe determinar si otro usuario la ha modificado o no desde que
se leyó. La simultaneidad optimista suele utilizarse en entornos con poca contención de datos. Esto mejora el
rendimiento porque no es necesario bloquear registros, a la vez que el bloqueo de registros requiere recursos
adicionales del servidor. Además, para mantener bloqueos de registros es necesaria una conexión persistente con
el servidor de bases de datos. Como éste no es el caso en un modelo de simultaneidad optimista, las conexiones
con el servidor pueden atender a un mayor número de clientes en menos tiempo.
En un modelo de simultaneidad optimista, se considera que ha habido una infracción si, después de que un usuario
recibe un valor de la base de datos, otro usuario modifica el valor antes de que el primer usuario haya intentado
modificarlo. En el ejemplo siguiente se describe cómo el servidor resuelve una infracción de simultaneidad.
Las siguientes tablas muestran un ejemplo de simultaneidad optimista.
A la 1:00 p.m., el Usuario1 lee una fila de la base de datos con los valores siguientes:
IdCliente Apellido Nombre
101 Martínez Cris
VA LO R EN L A B A SE DE
N O M B RE DE L A C O L UM N A VA LO R O RIGIN A L VA LO R A C T UA L DATO S
VA LO R EN L A B A SE DE
N O M B RE DE L A C O L UM N A VA LO R O RIGIN A L VA LO R A C T UA L DATO S
La actualización se realiza correctamente porque los valores contenidos en la base de datos en el momento de la
actualización coinciden con los valores originales que tiene el Usuario2.
A la 1:05 p.m., el Usuario1 cambia el nombre de "Cris" a "Jaime" e intenta actualizar la fila.
VA LO R EN L A B A SE DE
N O M B RE DE L A C O L UM N A VA LO R O RIGIN A L VA LO R A C T UA L DATO S
En este momento, el Usuario1 encuentra una infracción de la simultaneidad optimista porque los valores de la base
de datos ("Jaime") ya no coinciden con los valores originales que esperaba el Usuario1 ("Cris"). La infracción de
simultaneidad simplemente permite saber que se ha producido un error de actualización. Ahora hay que tomar la
decisión de sobrescribir los cambios realizados por el Usuario2 con los efectuados por el Usuario1 o cancelar los
cambios del Usuario1.
Para comprobar si hay una infracción de simultaneidad optimista al actualizar una fila en Table1 , se emitirá la
siguiente instrucción UPDATE:
La actualización se realizará siempre y cuando los valores originales coincidan con los valores de la base de datos.
Si se ha modificado algún valor, la actualización no modificará la fila porque la cláusula WHERE no encontrará
ninguna coincidencia.
Se recomienda devolver siempre un valor de clave principal único en la consulta. De lo contrario, la instrucción
UPDATE anterior puede actualizar más de una fila, lo que quizás no sea su intención.
Si una columna del origen de datos admite valores nulos, quizás sea necesario extender la cláusula WHERE para
comprobar si hay alguna referencia nula coincidente en la tabla local y en el origen de datos. Por ejemplo, la
siguiente instrucción UPDATE comprueba que una referencia nula de la fila local sigue coincidiendo con una
referencia nula del origen de datos o que el valor de la fila local sigue coincidiendo con el valor del origen de datos.
También se puede decidir la aplicación de criterios menos restrictivos al utilizar un modelo de simultaneidad
optimista. Por ejemplo, si solo se utilizan las columnas de clave principal en la cláusula WHERE se sobrescribirán
los datos, independientemente de que las otras columnas se hayan actualizado o no desde la última consulta.
También se puede aplicar una cláusula WHERE solo a determinadas columnas, lo que hará que se sobrescriban los
datos a menos que se hayan actualizado ciertos campos desde que se consultaron por última vez.
Evento DataAdapter.RowUpdated
El evento RowUpdated del DataAdapter objeto se puede usar junto con las técnicas descritas anteriormente para
proporcionar una notificación a la aplicación de infracciones de simultaneidad optimista. RowUpdated se produce
después de cada intento de actualizar una fila Modified desde un DataSet . Esto permite agregar código especial
de control, incluyendo el procesamiento cuando se produce una excepción, agregar información de error
personalizada, agregar lógica de reintento, etc. El RowUpdatedEventArgs objeto devuelve una propiedad
RecordsAffected que contiene el número de filas afectadas por un comando de actualización determinado para
una fila modificada de una tabla. Al establecer el comando update para probar la simultaneidad optimista, la
propiedad RecordsAffected, como resultado, devolverá un valor de 0 cuando se haya producido una infracción
de simultaneidad optimista, porque no se actualizó ningún registro. En tal caso se inicia una excepción. El evento
RowUpdated permite controlar esta aparición y evitar la excepción estableciendo un valor
RowUpdatedEventArgs.Status adecuado, como UpdateStatus.SkipCurrentRow . Para obtener más
información sobre el evento RowUpdated, vea Controlar eventos DataAdapter.
Opcionalmente, puede establecer DataAdapter.ContinueUpdateOnError en true , antes de llamar a Update y
responder a la información de error almacenada en la propiedad RowError de una fila determinada cuando se
completa la actualización. Para obtener más información, consulte Información de error de fila.
Ejemplo de simultaneidad optimista
A continuación se muestra un ejemplo sencillo que establece el UpdateCommand de un DataAdapter para
probar la simultaneidad optimista y, a continuación, usa el RowUpdated eventos para probar las infracciones de
simultaneidad optimista. Cuando se encuentra una infracción de simultaneidad optimista, la aplicación establece el
RowError de la fila para la que se emitió la actualización para reflejar una infracción de simultaneidad optimista.
Tenga en cuenta que los valores de parámetro pasados a la cláusula WHERE del comando UPDATE se asignan a los
valores Original de sus respectivas columnas.
adapter.Update(dataSet, "Customers");
Consulte también
Recuperar y modificar datos en ADO.NET
Actualizar orígenes de datos con objetos DataAdapter
Información de error de fila
Transacciones y simultaneidad
Información general de ADO.NET
Recuperar valores autonuméricos y de identidad
23/10/2019 • 33 minutes to read • Edit Online
Una clave principal de una base de datos relacional es una columna o combinación de columnas que siempre
contienen valores únicos. Conocer el valor de la clave principal permite localizar la fila que la contiene. Los
motores de bases de datos relacionales, como SQL Server, Oracle y Microsoft Access/Jet admiten la creación de
columnas de incremento automático que pueden designarse como claves principales. Estos valores los genera el
servidor cuando se agregan filas a una tabla. En SQL Server se establece la propiedad de identidad de una
columna, en Oracle se crea una secuencia y en Microsoft Access se crea una columna Autonumérica.
DataColumn también se puede utilizar para generar de manera automática valores incrementales estableciendo
la propiedad AutoIncrement en true. No obstante, podría haber valores duplicados en instancias distintas de
DataTable si varias aplicaciones cliente están generando por separado valores incrementales de manera
automática. Si se tiene un servidor que genera de manera automática valores incrementales se eliminan posibles
conflictos, pues se permite a cada usuario recuperar el valor generado para cada fila insertada.
Durante una llamada al método Update de DataAdapter , la base de datos puede volver a enviar datos a la
aplicación ADO.NET como parámetros de salida o como el primer registro devuelto del conjunto de resultados de
una instrucción SELECT ejecutada en el mismo lote que la instrucción INSERT. ADO.NET puede recuperar estos
valores y actualizar las columnas correspondientes en el DataRow que se está actualizando.
Algunos motores de base de datos, como los de Microsoft Access Jet, no admiten parámetros de salida y no
pueden procesar varias instrucciones en un único lote. Cuando trabaje con el motor de base de datos de Jet,
puede recuperar el nuevo valor Autonumérico generado para una fila insertada ejecutando un comando SELECT
distinto en un controlador de eventos para el evento RowUpdated de DataAdapter .
NOTE
Una opción alternativa al uso de un valor de incremento automático es utilizar el método NewGuid de un objeto Guid para
generar un GUID (identificador único global) en el equipo cliente que se pueda copiar al servidor cuando se inserte una
nueva fila. El método NewGuid genera un valor binario de 16 bits que se crea mediante un algoritmo que permite que
haya una alta probabilidad de que no se duplique ningún valor. En una base de datos de SQL Server, el GUID se almacena
en una columna uniqueidentifier que SQL Server puede generar automáticamente mediante la función Transact-SQL
NEWID() . Utilizar un GUID como clave principal puede afectar de manera negativa al rendimiento. SQL Server proporciona
compatibilidad con la NEWSEQUENTIALID() función, que genera un GUID secuencial que no se garantiza que sea
globalmente único, pero que se puede indizar de forma más eficaz.
F UN C IÓ N DESC RIP C IÓ N
El siguiente procedimiento almacenado muestra cómo insertar una fila en la tabla Categories y cómo utilizar un
parámetro de salida para devolver el nuevo valor de identidad generado por la función TRANSACT-SQL
SCOPE_IDENTITY ().
adapter.Update(categories);
Cuando se utiliza alguno de estos métodos para mantener los valores originales de DataRow durante una
actualización de DataAdapter , ADO.NET realiza una serie de acciones para establecer los valores actuales de
DataRow a los nuevos valores devueltos por parámetros de salida o por la primera fila devuelta de un conjunto
de resultados, al tiempo que se mantiene el valor original de cada DataColumn . Primero, se llama al método
AcceptChanges de DataRow para mantener los valores actuales como valores originales y, a continuación, se
asignan los nuevos valores. Después de estas acciones, las DataRows que tienen la propiedad RowState
establecida en Added tendrán su propiedad RowState establecida en Modified, lo que puede ser inesperado.
El modo en que se aplican los resultados del comando a cada DataRow que se actualiza lo determina la propiedad
UpdatedRowSource de cada DbCommand. Esta propiedad se establece en un valor desde la enumeración
UpdateRowSource .
La siguiente tabla describe cómo afectan los valores de enumeración UpdateRowSource a la propiedad RowState
de las filas actualizadas.
Ejemplo
Este ejemplo muestra la extracción de filas modificadas desde DataTable y el uso de SqlDataAdapter para
actualizar el origen de datos y recuperar un nuevo valor de columna de identidad. InsertCommand ejecuta dos
instrucciones Transact-SQL; la primera es la instrucción INSERT y la segunda es la instrucción SELECT.
INSERT INTO dbo.Shippers (CompanyName)
VALUES (@CompanyName);
SELECT ShipperID, CompanyName FROM dbo.Shippers
WHERE ShipperID = SCOPE_IDENTITY();
adapter.Update(dataChanges);
connection.Close();
// Create a DataTable
DataTable categories = new DataTable();
El controlador de eventos RowUpdated utiliza el mismo OleDbConnection abierto que la instrucción Update de
OleDbDataAdapter . Comprueba el StatementType de OleDbRowUpdatedEventArgs de las filas insertadas. Para
cada fila insertada, OleDbCommand se crea un nuevo para ejecutar la@IDENTITY instrucción SELECT @ en la
conexión, devolviendo el nuevo Autonumber valor, que DataRow se coloca en la columna Categor yID de. La
propiedad Status se establece luego en UpdateStatus.SkipCurrentRow para suprimir la llamada oculta a
AcceptChanges . En el cuerpo principal del procedimiento, se llama al método Merge para fusionar mediante
combinación los dos objetos DataTable y, finalmente, se llama a AcceptChanges .
USE [master]
GO
USE [MySchool]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE procedure [dbo].[CourseExtInfo] @CourseId int
as
select c.CourseID,c.Title,c.Credits,d.Name as DepartmentName
from Course as c left outer join Department as d on c.DepartmentID=d.DepartmentID
where c.CourseID=@CourseId
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create procedure [dbo].[DepartmentInfo] @DepartmentId int,@CourseCount int output
as
select @CourseCount=Count(c.CourseID)
from course as c
where c.DepartmentID=@DepartmentId
select d.DepartmentID,d.Name,d.Budget,d.StartDate,d.Administrator
from Department as d
where d.DepartmentID=@DepartmentId
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create PROCEDURE [dbo].[GetDepartmentsOfSpecifiedYear]
@Year int,@BudgetSum money output
AS
BEGIN
SELECT @BudgetSum=SUM([Budget])
FROM [MySchool].[dbo].[Department]
Where YEAR([StartDate])=@Year
SELECT [DepartmentID]
,[Name]
,[Budget]
,[StartDate]
,[Administrator]
FROM [MySchool].[dbo].[Department]
Where YEAR([StartDate])=@Year
END
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[GradeOfStudent]
-- Add the parameters for the stored procedure here
@CourseTitle nvarchar(100),@FirstName nvarchar(50),
@LastName nvarchar(50),@Grade decimal(3,2) output
AS
BEGIN
select @Grade=Max(Grade)
from [dbo].[StudentGrade] as s join [dbo].[Course] as c on
s.CourseID=c.CourseID join [dbo].[Person] as p on s.StudentID=p.PersonID
where c.Title=@CourseTitle and p.FirstName=@FirstName
and p.LastName= @LastName
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[InsertPerson]
-- Add the parameters for the stored procedure here
@FirstName nvarchar(50),@LastName nvarchar(50),
@PersonID int output
AS
BEGIN
insert [dbo].[Person](LastName,FirstName) Values(@LastName,@FirstName)
set @PersonID=SCOPE_IDENTITY()
END
Go
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Course]([CourseID] [nvarchar](10) NOT NULL,
[Year] [smallint] NOT NULL,
[Title] [nvarchar](100) NOT NULL,
[Credits] [int] NOT NULL,
[DepartmentID] [int] NOT NULL,
CONSTRAINT [PK_Course] PRIMARY KEY CLUSTERED
(
[CourseID] ASC,
[Year] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Department]([DepartmentID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Budget] [money] NOT NULL,
[StartDate] [datetime] NOT NULL,
[Administrator] [int] NULL,
CONSTRAINT [PK_Department] PRIMARY KEY CLUSTERED
(
[DepartmentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Person]([PersonID] [int] IDENTITY(1,1) NOT NULL,
[LastName] [nvarchar](50) NOT NULL,
[FirstName] [nvarchar](50) NOT NULL,
[HireDate] [datetime] NULL,
[EnrollmentDate] [datetime] NULL,
[Picture] [varbinary](max) NULL,
CONSTRAINT [PK_School.Student] PRIMARY KEY CLUSTERED
(
[PersonID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[StudentGrade]([EnrollmentID] [int] IDENTITY(1,1) NOT NULL,
[CourseID] [nvarchar](10) NOT NULL,
[StudentID] [int] NOT NULL,
[Grade] [decimal](3, 2) NOT NULL,
CONSTRAINT [PK_StudentGrade] PRIMARY KEY CLUSTERED
(
[EnrollmentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create view [dbo].[EnglishCourse]
as
select c.CourseID,c.Title,c.Credits,c.DepartmentID
from Course as c join Department as d on c.DepartmentID=d.DepartmentID
where d.Name=N'English'
GO
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C1045', 2012,
N'Calculus', 4, 7)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C1061', 2012,
N'Physics', 4, 1)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C2021', 2012,
N'Composition', 3, 2)
INSERT [dbo].[Course] ([CourseID], [Year], [Title], [Credits], [DepartmentID]) VALUES (N'C2042', 2012,
N'Literature', 4, 2)
SET IDENTITY_INSERT [dbo].[Department] ON
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (1, N'Hu',
N'Nan', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (2,
N'Norman', N'Laura', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (3,
N'Olivotto', N'Nino', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (4,
N'Anand', N'Arturo', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (5, N'Jai',
N'Damien', NULL, CAST(0x0000A0BF00000000 AS DateTime))
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (6, N'Holt',
N'Roger', CAST(0x000097F100000000 AS DateTime), NULL)
INSERT [dbo].[Person] ([PersonID], [LastName], [FirstName], [HireDate], [EnrollmentDate]) VALUES (7,
N'Martin', N'Randall', CAST(0x00008B1A00000000 AS DateTime), NULL)
SET IDENTITY_INSERT [dbo].[Person] OFF
SET IDENTITY_INSERT [dbo].[StudentGrade] ON
using System;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
class Program {
static void Main(string[] args) {
String SqlDbConnectionString = "Data Source=(local);Initial Catalog=MySchool;Integrated
Security=True;Asynchronous Processing=true;";
// Using stored procedure to insert a new row and retrieve the identity value
static void InsertPerson(String connectionString, String firstName, String lastName) {
String commandText = "dbo.InsertPerson";
conn.Open();
cmd.ExecuteNonQuery();
// Using stored procedure in adapter to insert new rows and update the identity value.
static void InsertPersonInAdapter(String connectionString, String firstName, String lastName) {
String commandText = "dbo.InsertPerson";
using (SqlConnection conn = new SqlConnection(connectionString)) {
SqlDataAdapter mySchool = new SqlDataAdapter("Select PersonID,FirstName,LastName from [dbo].
[Person]", conn);
mySchool.InsertCommand.Parameters.Add(
new SqlParameter("@FirstName", SqlDbType.NVarChar, 50, "FirstName"));
mySchool.InsertCommand.Parameters.Add(
new SqlParameter("@LastName", SqlDbType.NVarChar, 50, "LastName"));
SqlParameter personId = mySchool.InsertCommand.Parameters.Add(new SqlParameter("@PersonID",
SqlDbType.Int, 0, "PersonID"));
personId.Direction = ParameterDirection.Output;
mySchool.Update(persons);
Console.WriteLine("Show all persons:");
ShowDataTable(persons, 14);
}
}
/// For a Jet 4.0 database, we need use the single statement and event handler to insert new rows and
retrieve the identity value.
static void InsertPersonInJet4Database(String connectionString, String firstName, String lastName) {
String commandText = "Insert into Person(FirstName,LastName) Values(?,?)";
using (OleDbConnection conn = new OleDbConnection(connectionString)) {
OleDbDataAdapter mySchool = new OleDbDataAdapter("Select PersonID,FirstName,LastName from Person",
conn);
mySchool.Fill(persons);
mySchool.RowUpdated += OnRowUpdated;
mySchool.Update(dataChanges);
persons.Merge(dataChanges);
persons.AcceptChanges();
return persons;
}
Console.WriteLine();
}
}
}
Vea también
Recuperar y modificar datos en ADO.NET
Objetos DataAdapter y DataReader
Estados y versiones de filas
AcceptChange y RejectChange
Combinar contenido de DataSet
Actualizar orígenes de datos con objetos DataAdapter
Información general sobre ADO.NET
Recuperación de datos binarios
21/03/2020 • 8 minutes to read • Edit Online
De forma predeterminada, el DataReader carga los datos entrantes como una fila tan pronto como una fila
completa de datos está disponible. Sin embargo, los objetos binarios grandes (BLOB) se deben tratar de otra forma,
ya que pueden llegar a contener grandes cantidades de datos (del orden de gigabytes) que no pueden almacenarse
en una sola fila. El método Command.ExecuteReader tiene una CommandBehavior sobrecarga que tomará un
argumento para modificar el comportamiento predeterminado de DataReader . Puede pasar SequentialAccess al
método ExecuteReader para modificar el comportamiento predeterminado de DataReader para que, en lugar de
cargar filas de datos, cargue los datos secuencialmente a medida que se reciban. Este sistema es idóneo para
cargar BLOB y otras estructuras de datos grandes. Tenga en cuenta que este comportamiento puede depender del
origen de datos. Por ejemplo, si se devuelve un BLOB desde Microsoft Access, el BLOB completo se cargará en
memoria, en lugar de hacerlo secuencialmente a medida que se recibe.
Al establecer DataReader para usar SequentialAccess , es importante tener en cuenta la secuencia en la que se
tiene acceso a los campos devueltos. El comportamiento predeterminado de DataReader , que carga una fila
completa tan pronto como está disponible, le permite tener acceso a los campos devueltos en cualquier orden
hasta que se lea la siguiente fila. Sin embargo, al usar SequentialAccess, debe tener acceso a los campos
devueltos por El DataReader en orden. Por ejemplo, si la consulta devuelve tres columnas y la tercera es un BLOB,
debe devolver los valores de los campos primero y segundo antes de tener acceso a los datos BLOB del tercer
campo. Si trata de tener acceso al tercer campo antes que al primero o el segundo, puede que éstos dejen de estar
disponibles. Esto se debe a que SequentialAccess ha modificado el DataReader para devolver datos en
secuencia y los datos no están disponibles después de que DataReader lo haya leído más allá de él.
Al tener acceso a los datos en el campo BLOB, utilice los descriptores de acceso con tipo GetBytes o GetChars de
DataReader , que rellenan una matriz con datos. También puede usar GetString para los datos de caracteres; Sin
embargo. si desea conservar los recursos del sistema, es mejor que no cargue un valor BLOB completo en una sola
variable de cadena. En lugar de ello, puede especificar un tamaño determinado de búfer para los datos que se van a
devolver, así como la ubicación de comienzo para leer el primer byte o carácter de los datos devueltos. GetBytes y
GetChars long devolverán un valor, que representa el número de bytes o caracteres devueltos. Si pasa una
matriz null a GetBytes o GetChars , el valor long devuelto será el número total de bytes o caracteres en el BLOB.
También puede especificar un índice de la matriz como posición de comienzo para la lectura de datos.
Ejemplo
En el ejemplo siguiente se devuelve el identificador de publicador y el logotipo de la base de datos de ejemplo
pubs en Microsoft SQL Server. El identificador del publicador ( pub_id ) es un campo de caracteres, mientras que el
logotipo es una imagen de BLOB. Dado que el campo logo es un mapa de bits, el ejemplo devuelve datos binarios
mediante GetBytes . Tenga en cuenta que la necesidad de tener acceso a los datos de forma secuencial hace que en
la fila actual de datos se tenga acceso al identificador de publicador antes que al logotipo.
' Assumes that connection is a valid SqlConnection object.
Dim command As SqlCommand = New SqlCommand( _
"SELECT pub_id, logo FROM pub_info", connection)
' Open the connection and read data into the DataReader.
connection.Open()
Dim reader As SqlDataReader = command.ExecuteReader(CommandBehavior.SequentialAccess)
Do While reader.Read()
' Get the publisher id, which must occur before getting the logo.
pubID = reader.GetString(0)
' Read bytes into outByte() and retain the number of bytes returned.
retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize)
' Continue while there are bytes beyond the size of the buffer.
Do While retval = bufferSize
writer.Write(outByte)
writer.Flush()
' Reposition start index to end of the last buffer and fill buffer.
startIndex += bufferSize
retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize)
Loop
while (reader.Read())
{
// Get the publisher id, which must occur before getting the logo.
pubID = reader.GetString(0);
// Read bytes into outByte[] and retain the number of bytes returned.
retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);
// Continue while there are bytes beyond the size of the buffer.
while (retval == bufferSize)
{
writer.Write(outByte);
writer.Flush();
Los procedimientos almacenados pueden aceptar datos como parámetros de entrada y pueden devolver datos
como parámetros de salida, conjuntos de resultados o valores de retorno. En el ejemplo siguiente se muestra
cómo ADO.NET envía y recibe parámetros de entrada, parámetros de salida y valores de retorno. El ejemplo
inserta un nuevo registro en una tabla cuya columna de clave principal es una columna de identidad en una base
de datos de SQL Server.
NOTE
Si está utilizando procedimientos almacenados de SQL Server para editar o eliminar datos con SqlDataAdapter, asegúrese de
que no utiliza SET NOCOUNT ON en la definición del procedimiento almacenado. Esto hace que el recuento de filas afectadas
vuelva a cero, lo que DataAdapter interpreta como un conflicto de simultaneidad. En este caso, se iniciará una
DBConcurrencyException.
Ejemplo
En el ejemplo se usa el siguiente procedimiento almacenado para insertar una nueva categoría en la tabla
Categories de Nor thwind . El procedimiento almacenado toma el valor de la columna Categor yName como
parámetro de entrada y usa la función SCOPE_IDENTITY () para recuperar el nuevo valor del campo de identidad,
Categor yID , y devolverlo en un parámetro de salida. La instrucción return utiliza la@ROWCOUNT función @
para devolver el número de filas insertadas.
En el siguiente ejemplo de código se utiliza el anterior procedimiento almacenado InsertCategory como origen de
la propiedad InsertCommand de SqlDataAdapter. El parámetro de salida @Identity se reflejará en DataSet una
vez que se haya insertado el registro en la base de dados al llamar al método Update del SqlDataAdapter. El
código también recupera el valor devuelto.
NOTE
Al utilizar OleDbDataAdapter, debe especificar los parámetros con un ParameterDirection de ReturnValue antes que los
demás parámetros.
using System;
using System.Data;
using System.Data.SqlClient;
class Program
{
static void Main()
{
string connectionString = GetConnectionString();
ReturnIdentity(connectionString);
// Console.ReadLine();
}
Option Explicit On
Option Strict On
Imports System.Data
Imports System.Data.SqlClient
Module Class1
Sub Main()
Dim connectionString As String = _
GetConnectionString()
ReturnIdentity(connectionString)
' Console.ReadLine()
End Sub
End Module
Vea también
Recuperar y modificar datos en ADO.NET
Objetos DataAdapter y DataReader
Ejecución de un comando
Información general sobre ADO.NET
Recuperar información del esquema de la base de
datos
23/10/2019 • 4 minutes to read • Edit Online
La obtención de información de esquema de una base de datos se efectúa con el proceso de detección de
esquemas. La detección de esquemas permite a las aplicaciones solicitar que los proveedores administrados
busquen y devuelvan información sobre el esquema de la base de datos, también conocido como metadatos, de
una base de datos determinada. Los diferentes elementos del esquema de base de datos, como tablas, columnas y
procedimientos almacenados, se exponen a través de colecciones de esquemas. Cada colección de esquemas
contiene diversa información de esquema relativa al proveedor que se está utilizando.
Cada uno de los proveedores administrados de .NET Framework implementa el método GetSchema en la clase
Connection , y la información de esquema que se devuelve desde el método GetSchema tiene el
DataTableformato. El método GetSchema es un método sobrecargado que proporciona parámetros opcionales
para especificar la colección de esquemas que se va a devolver y restringir la cantidad de información devuelta.
Los proveedores de datos de .NET Framework para OLE DB, ODBC, Oracle y SqlClient proporcionan un método
GetSchemaTable que devuelve un DataTable que describe los metadatos de columna del DataReader .
Además el proveedor de datos .NET Framework para OLE DB también expone información de esquema mediante
el método GetOleDbSchemaTable del objeto OleDbConnection. Como argumentos, GetOleDbSchemaTable
toma un OleDbSchemaGuid que identifica la información de esquema que se va a devolver y una matriz de
restricciones en esas columnas devueltas. GetOleDbSchemaTable devuelve un DataTable rellenado con la
información de esquema solicitada.
En esta sección
GetSchema y colecciones de esquema
Describe el método GetSchema y cómo se puede utilizar para recuperar y restringir la información de esquema
de una base de datos.
Restricciones de esquema
Describe las restricciones de esquema que se pueden usar con GetSchema .
Colecciones de esquemas comunes
Describe todas las colecciones de esquemas comunes que admiten todos los proveedores administrados de .NET
Framework.
Colecciones de esquemas de SQL Server
Describe la colección de esquemas compatibles con el proveedor de datos .NET Framework para SQL Server.
Colecciones de esquemas de Oracle
Describe la colección de esquemas compatibles con el proveedor de datos .NET Framework para Oracle.
Colecciones de esquemas de ODBC
Describe las colecciones de esquemas para los controladores ODBC.
Colecciones de esquemas de OLE DB
Describe las colecciones de esquemas para los proveedores OLE DB.
Referencia
GetSchema
Describe el método GetSchema de la DbConnection clase.
GetSchema
Describe el método GetSchema de la OdbcConnection clase.
GetSchema
Describe el método GetSchema de la OleDbConnection clase.
GetSchema
Describe el método GetSchema de la OracleConnection clase.
GetSchema
Describe el método GetSchema de la SqlConnection clase.
GetSchemaTable
Describe el método GetSchemaTable de la DbDataReader clase.
GetSchemaTable
Describe el método GetSchemaTable de la OdbcDataReader clase.
GetSchemaTable
Describe el método GetSchemaTable de la OleDbDataReader clase.
GetSchemaTable
Describe el método GetSchemaTable de la OracleDataReader clase.
GetSchemaTable
Describe el método GetSchemaTable de la SqlDataReader clase.
Vea también
Recuperar y modificar datos en ADO.NET
Información general sobre ADO.NET
GetSchema y colecciones de esquema
21/03/2020 • 3 minutes to read • Edit Online
Las clases connection de cada uno de los proveedores administrados de .NET Framework implementan un
método GetSchema que se usa para recuperar DataTableinformación de esquema sobre la base de datos que está
conectada actualmente y la información de esquema devuelta desde el método GetSchema viene en forma de
archivo . El GetSchema método es un método sobrecargado que proporciona parámetros opcionales para
especificar la colección de esquemas que se va a devolver y restringir la cantidad de información devuelta.
Module Module1
Sub Main()
Dim connectionString As String = GetConnectionString()
Using connection As New SqlConnection(connectionString)
'Connect to the database then retrieve the schema information.
connection.Open()
Dim table As DataTable = connection.GetSchema("Tables")
class Program
{
static void Main()
{
string connectionString = GetConnectionString();
using (SqlConnection connection = new SqlConnection(connectionString))
{
// Connect to the database then retrieve the schema information.
connection.Open();
DataTable table = connection.GetSchema("Tables");
Consulte también
Recuperación de información del esquema de la base de datos
Información general de ADO.NET
Restricciones de esquema
21/03/2020 • 9 minutes to read • Edit Online
El segundo parámetro opcional del método GetSchema son las restricciones que se usan para limitar la cantidad
de información de esquema devuelta y se pasa al método GetSchema como una matriz de cadenas. La posición en
la matriz determina los valores que puede pasar, y es equivalente al número de restricciones.
Por ejemplo, en la tabla siguiente se describen las restricciones que admite la colección de esquemas "Tables"
utilizando el proveedor de datos .NET Framework para SQL Server. Las restricciones adicionales para las
colecciones de esquemas de SQL Server se muestran al final de este tema.
N O M B RE DE L A VA LO R P REDET ERM IN A DO
REST RIC C IÓ N N O M B RE DE PA RÁ M ET RO DE L A REST RIC C IÓ N N ÚM ERO DE REST RIC C IO N ES
NOTE
Las colecciones con restricciones para SqlClient y OracleClient tienen una columna ParameterName adicional. La
columna de valor predeterminado de restricción sigue ahí para la compatibilidad con versiones anteriores, pero actualmente
se omite. Para reducir el riesgo de un ataque de inyección de SQL al especificar valores de restricción, es necesario utilizar
consultas parametrizadas en lugar de sustitución de cadenas.
NOTE
El número de elementos de la matriz debe ser menor o igual que el número de restricciones admitidas en la colección de
esquemas especificada o se iniciará una ArgumentException. Puede haber un número de restricciones inferior al máximo. Se
supone que las restricciones que faltan serán nulas (sin restricciones).
Puede consultar un proveedor administrado de .NET Framework para determinar la lista de restricciones admitidas
llamando al método GetSchema con el nombre de la colección de esquemas de restricciones, que es
"Restrictions". Esto devolverá una DataTable con una lista de los nombres de colecciones, los nombres de
restricciones, los valores predeterminados de restricción y los números de restricciones.
Ejemplo
En los ejemplos siguientes GetSchema se muestra cómo utilizar el método SqlConnection del proveedor de datos
de .NET Framework para la clase de SQL ServerSQL Server para recuperar información de esquema sobre todas las
tablas contenidas en la base de datos de ejemplo AdventureWorks y restringir la información devuelta solo a las
tablas del esquema "Sales":
Imports System.Data.SqlClient
Module Module1
Sub Main()
Dim connectionString As String = _
"Data Source=(local);Database=AdventureWorks;" & _
"Integrated Security=true;";
class Program
{
static void Main()
{
string connectionString =
"Data Source=(local);Database=AdventureWorks;" +
"Integrated Security=true;";
using (SqlConnection connection =
new SqlConnection(connectionString))
{
connection.Open();
Bases de datos
N O M B RE DE L A VA LO R P REDET ERM IN A DO
REST RIC C IÓ N N O M B RE DE PA RÁ M ET RO DE L A REST RIC C IÓ N N ÚM ERO DE REST RIC C IO N ES
Tablas
N O M B RE DE L A VA LO R P REDET ERM IN A DO
REST RIC C IÓ N N O M B RE DE PA RÁ M ET RO DE L A REST RIC C IÓ N N ÚM ERO DE REST RIC C IO N ES
Columnas
N O M B RE DE L A VA LO R P REDET ERM IN A DO
REST RIC C IÓ N N O M B RE DE PA RÁ M ET RO DE L A REST RIC C IÓ N N ÚM ERO DE REST RIC C IO N ES
StructuredTypeMembers
N O M B RE DE L A VA LO R P REDET ERM IN A DO
REST RIC C IÓ N N O M B RE DE PA RÁ M ET RO DE L A REST RIC C IÓ N N ÚM ERO DE REST RIC C IO N ES
Vistas
N O M B RE DE L A VA LO R P REDET ERM IN A DO
REST RIC C IÓ N N O M B RE DE PA RÁ M ET RO DE L A REST RIC C IÓ N N ÚM ERO DE REST RIC C IO N ES
ViewColumns
N O M B RE DE L A VA LO R P REDET ERM IN A DO
REST RIC C IÓ N N O M B RE DE PA RÁ M ET RO DE L A REST RIC C IÓ N N ÚM ERO DE REST RIC C IO N ES
ProcedureParameters
N O M B RE DE L A VA LO R P REDET ERM IN A DO
REST RIC C IÓ N N O M B RE DE PA RÁ M ET RO DE L A REST RIC C IÓ N N ÚM ERO DE REST RIC C IO N ES
Procedimientos
N O M B RE DE L A VA LO R P REDET ERM IN A DO
REST RIC C IÓ N N O M B RE DE PA RÁ M ET RO DE L A REST RIC C IÓ N N ÚM ERO DE REST RIC C IO N ES
IndexColumns
N O M B RE DE L A VA LO R P REDET ERM IN A DO
REST RIC C IÓ N N O M B RE DE PA RÁ M ET RO DE L A REST RIC C IÓ N N ÚM ERO DE REST RIC C IO N ES
Índices
N O M B RE DE L A VA LO R P REDET ERM IN A DO
REST RIC C IÓ N N O M B RE DE PA RÁ M ET RO DE L A REST RIC C IÓ N N ÚM ERO DE REST RIC C IO N ES
UserDefinedTypes
N O M B RE DE L A VA LO R P REDET ERM IN A DO
REST RIC C IÓ N N O M B RE DE PA RÁ M ET RO DE L A REST RIC C IÓ N N ÚM ERO DE REST RIC C IO N ES
ForeignKeys
N O M B RE DE L A VA LO R P REDET ERM IN A DO
REST RIC C IÓ N N O M B RE DE PA RÁ M ET RO DE L A REST RIC C IÓ N N ÚM ERO DE REST RIC C IO N ES
AllColumns
N O M B RE DE L A VA LO R P REDET ERM IN A DO
REST RIC C IÓ N N O M B RE DE PA RÁ M ET RO DE L A REST RIC C IÓ N N ÚM ERO DE REST RIC C IO N ES
Consulte también
Información general de ADO.NET
Colecciones de esquemas comunes
27/03/2020 • 21 minutes to read • Edit Online
Las colecciones de esquemas comunes son las colecciones de esquemas que implementa cada uno de los
proveedores administrados de .NET Framework. Puede consultar un proveedor administrado de .NET Framework
para determinar la lista de colecciones de esquemas compatibles llamando al método GetSchema sin argumentos
o con el nombre de colección de esquemas "MetaDataCollections". Esto devolverá una DataTable con una lista de
colecciones de esquemas admitidas, el número de restricciones que admite cada una y el número de partes de
identificador que emplean. Estas colecciones describen todas las columnas necesarias. Los proveedores pueden
agregar más columnas si lo desean. Por ejemplo, SqlClient y OracleClient agregan ParameterName a la
colección con restricciones.
Si un proveedor no puede determinar el valor de una columna necesaria, se devolverá NULL.
Para obtener más información sobre el uso de los métodos GetSchema, vea GetSchema y Coleccionesde
esquemas .
MetaDataCollections
Esta colección de esquemas expone información acerca de las colecciones de esquemas que admite el proveedor
administrado de .NET Framework que se utiliza actualmente para conectarse a la base de datos.
DataSourceInformation
Esta colección de esquemas expone información acerca del origen de datos al que actualmente está conectado el
proveedor administrado de .NET Framework.
En ODBC, utilice
Catalog_name_seperator.
En algunos casos,
DataSourceProductVersion y
DataSourceProductVersionNormalized
tendrán el mismo valor. En el caso de
OLE DB y ODBC, serán siempre iguales
dado que se asignan a la misma llamada
de función en la API nativa subyacente.
C O L UM N N A M E DATAT Y P E DESC RIP C IÓ N
En algunos casos,
DataSourceProductVersion y
DataSourceProductVersionNormalized
tendrán el mismo valor. En el caso de
OLE DB y ODBC, serán siempre iguales
dado que se asignan a la misma llamada
de función en la API nativa subyacente.
DataTypes
Esta colección de esquemas expone información acerca de los tipos de datos que admite la base de datos a la que
está conectado actualmente el proveedor de datos de .NET Framework.
Restricciones
Esta colección de esquemas expone información acerca de las restricciones que admite el proveedor administrado
de .NET Framework que está actualmente conectado a la base de datos.
ReservedWords
Esta colección de esquemas expone información sobre las palabras que reserva la base de datos a la que está
conectado actualmente el proveedor de datos de .NET Framework.
Vea también
Recuperar información del esquema de la base de datos
GetSchema y colecciones de esquema
Información general sobre ADO.NET
Colecciones de esquemas de SQL Server
23/10/2019 • 24 minutes to read • Edit Online
El proveedor de datos .NET Framework para SQL Server de Microsoft admite colecciones de esquemas
adicionales, además de las colecciones de esquemas comunes. Las colecciones de esquemas varían ligeramente
respecto de la versión de SQL Server que está utilizando. Para determinar la lista de colecciones de esquemas
admitidas, llame al método GetSchema sin argumentos o con el nombre de la colección de esquemas
"MetaDataCollections". Esto devolverá una DataTable con una lista de colecciones de esquemas admitidas, el
número de restricciones que admite cada una y el número de partes de identificador que emplean.
Bases de datos
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Claves externas
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Índices
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
-MONTÓN
-AGRUPADO
-NONCLUSTERED
-XML
-ESPACIAL
IndexColumns
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Procedimientos
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Parámetros de procedimiento
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Tablas
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Columnas
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
NO si la columna no es de conjunto de
columnas.
NO si la columna no es de conjunto de
columnas.
NO si la columna no es de conjunto de
columnas.
Usuarios
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Vistas
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
ViewColumns
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
UserDefinedTypes
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Vea también
Recuperación de información del esquema de la base de datos
Información general sobre ADO.NET
Colecciones de esquemas de Oracle
23/10/2019 • 30 minutes to read • Edit Online
El proveedor de datos Microsoft .NET Framework para Oracle admite, además de las colecciones de esquemas
comunes, las siguientes colecciones de esquemas específicas:
Columnas
Índices
IndexColumns
Procedimientos
Secuencias
Sinónimos
Tablas
Usuarios
Vistas
Funciones
Paquetes
PackageBodies
Argumentos
UniqueKeys
PrimaryKeys
ForeignKeys
ForeignKeyColumns
ProcedureParameters
Columnas
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Índices
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
IndexColumns
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Procedimientos
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Secuencias
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Sinónimos
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Tablas
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Usuarios
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Vistas
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Funciones
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Paquetes
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
PackageBodies
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Argumentos
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
UniqueKeys
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
PrimaryKeys
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
ForeignKeys
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
ForeignKeyColumns
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
ProcedureParameters
C O L UM N A M E DATAT Y P E DESC RIP C IÓ N
Vea también
Información general sobre ADO.NET
Colecciones de esquemas de ODBC
23/10/2019 • 5 minutes to read • Edit Online
En esta sección se describe la compatibilidad de las colecciones de esquemas con los controladores ODBC de
Microsoft SQL Server, Oracle y Microsoft Jet.
TABLE_CAT string
TABLE_SCHEM string
TABLE_NAME string
TABLE_TYPE string
REMARKS string
Índices
C O L UM N A M E DATAT Y P E
TABLE_CAT string
TABLE_SCHEM string
TABLE_NAME string
NON_UNIQUE Int16
INDEX_QUALIFIER string
C O L UM N A M E DATAT Y P E
INDEX_NAME string
TYPE Int16
ORDINAL_POSITION Int16
COLUMN_NAME string
ASC_OR_DESC string
CARDINALITY Int32
PAGES Int32
FILTER_CONDITION string
SS_TYPE_SCHEMA string
SS_DATA_TYPE Byte
Columnas
C O L UM N A M E DATAT Y P E
TABLE_CAT string
TABLE_SCHEM string
TABLE_NAME string
COLUMN_NAME string
DATA_TYPE Int16
TYPE_NAME string
COLUMN_SIZE Int32
BUFFER_LENGTH Int32
DECIMAL_DIGITS Int16
NUM_PREC_RADIX Int16
NULLABLE Int16
REMARKS string
COLUMN_DEF string
C O L UM N A M E DATAT Y P E
SQL_DATA_TYPE Int16
SQL_DATETIME_SUB Int16
CHAR_OCTET_LENGTH Int32
ORDINAL_POSITION Int32
IS_NULLABLE string
SS_TYPE_CATALOG string
SS_TYPE_SCHEMA string
SS_DATA_TYPE Byte
Procedimientos
C O L UM N A M E DATAT Y P E
PROCEDURE_CAT string
PROCEDURE_SCHEM string
PROCEDURE_NAME string
NUM_INPUT_PARAMS Int32
NUM_OUTPUT_PARAMS Int32
NUM_RESULT_SETS Int32
REMARKS string
PROCEDURE_TYPE Int16
ProcedureColumns
C O L UM N A M E DATAT Y P E
PROCEDURE_CAT string
PROCEDURE_SCHEM string
PROCEDURE_NAME string
COLUMN_NAME string
COLUMN_TYPE Int16
DATA_TYPE Int16
C O L UM N A M E DATAT Y P E
TYPE_NAME string
COLUMN_SIZE Int32
BUFFER_LENGTH Int32
DECIMAL_DIGITS Int16
NUM_PREC_RADIX Int16
NULLABLE Int16
REMARKS string
COLUMN_DEF string
SQL_DATA_TYPE Int16
SQL_DATETIME_SUB Int16
CHAR_OCTET_LENGTH Int32
ORDINAL_POSITION Int32
IS_NULLABLE string
SS_TYPE_CATALOG string
SS_TYPE_SCHEMA string
SS_DATA_TYPE Byte
ProcedureParameters
C O L UM N A M E DATAT Y P E
PROCEDURE_CAT string
PROCEDURE_SCHEM string
PROCEDURE_NAME string
COLUMN_NAME string
COLUMN_TYPE Int16
DATA_TYPE Int16
TYPE_NAME string
C O L UM N A M E DATAT Y P E
COLUMN_SIZE Int32
BUFFER_LENGTH Int32
DECIMAL_DIGITS Int16
NUM_PREC_RADIX Int16
NULLABLE Int16
REMARKS string
COLUMN_DEF string
SQL_DATA_TYPE Int16
SQL_DATETIME_SUB Int16
CHAR_OCTET_LENGTH Int32
ORDINAL_POSITION Int32
IS_NULLABLE string
SS_TYPE_CATALOG string
SS_TYPE_SCHEMA string
SS_DATA_TYPE Byte
TABLE_QUALIFIER string
TABLE_OWNER string
TABLE_NAME string
TABLE_TYPE string
REMARKS string
Columnas
C O L UM N A M E DATAT Y P E
TABLE_QUALIFIER string
TABLE_OWNER string
TABLE_NAME string
COLUMN_NAME string
DATA_TYPE Int16
TYPE_NAME string
PRECISION Int32
LENGTH Int32
SCALE Int16
RADIX Int16
NULLABLE Int16
REMARKS string
ORDINAL_POSITION Int32
Procedimientos
C O L UM N A M E DATAT Y P E
PROCEDURE_QUALIFIER string
PROCEDURE_OWNER string
PROCEDURE_NAME string
NUM_INPUT_PARAMS Int16
C O L UM N A M E DATAT Y P E
NUM_OUTPUT_PARAMS Int16
NUM_RESULT_SETS Int16
REMARKS string
PROCEDURE_TYPE Int16
ProcedureColumns
C O L UM N A M E DATAT Y P E
PROCEDURE_QUALIFIER string
PROCEDURE_OWNER string
PROCEDURE_NAME string
COLUMN_NAME string
COLUMN_TYPE Int16
DATA_TYPE Int16
TYPE_NAME string
PRECISION Int32
LENGTH Int32
SCALE Int16
RADIX Int16
NULLABLE Int16
REMARKS string
OVERLOAD Int32
ORDINAL_POSITION Int32
TABLE_QUALIFIER string
TABLE_OWNER string
TABLE_NAME string
TABLE_TYPE string
REMARKS string
Columnas
C O L UM N A M E DATAT Y P E
TABLE_QUALIFIER string
TABLE_OWNER string
TABLE_NAME string
COLUMN_NAME string
DATA_TYPE Int16
TYPE_NAME string
PRECISION Int32
LENGTH Int32
SCALE Int16
RADIX Int16
NULLABLE Int16
REMARKS string
ORDINAL_POSITION Int32
Procedimientos
C O L UM N A M E DATAT Y P E
PROCEDURE_QUALIFIER string
PROCEDURE_OWNER string
PROCEDURE_NAME string
NUM_INPUT_PARAMS Int16
NUM_OUTPUT_PARAMS Int16
NUM_RESULT_SETS Int16
REMARKS string
PROCEDURE_TYPE Int16
ProcedureColumns
C O L UM N A M E DATAT Y P E
PROCEDURE_QUALIFIER string
PROCEDURE_OWNER string
PROCEDURE_NAME string
COLUMN_NAME string
COLUMN_TYPE Int16
DATA_TYPE Int16
TYPE_NAME string
PRECISION Int32
LENGTH Int32
SCALE Int16
RADIX Int16
NULLABLE Int16
REMARKS string
OVERLOAD Int32
ORDINAL_POSITION Int32
ProcedureParameters
C O L UM N A M E DATAT Y P E
PROCEDURE_CAT string
PROCEDURE_SCHEM string
PROCEDURE_NAME string
COLUMN_NAME string
COLUMN_TYPE Int16
DATA_TYPE Int16
TYPE_NAME string
COLUMN_SIZE Int32
BUFFER_LENGTH Int32
DECIMAL_DIGITS Int16
NUM_PREC_RADIX Int16
NULLABLE Int16
REMARKS string
COLUMN_DEF string
SQL_DATA_TYPE Int16
SQL_DATETIME_SUB Int16
CHAR_OCTET_LENGTH Int32
ORDINAL_POSITION Int32
IS_NULLABLE string
Vea también
Información general sobre ADO.NET
Colecciones de esquemas de OLE DB
23/10/2019 • 7 minutes to read • Edit Online
En esta sección se describe la compatibilidad de las colecciones de esquemas con los proveedores OLE DB de
Microsoft SQL Server, Oracle y Microsoft Jet.
TABLE_CATALOG string
TABLE_SCHEMA string
TABLE_NAME string
TABLE_TYPE string
TABLE_GUID Guid
DESCRIPTION string
TABLE_PROPID Int64
DATE_CREATED DateTime
DATE_MODIFIED DateTime
Columnas
C O L UM N A M E DATAT Y P E
TABLE_CATALOG string
TABLE_SCHEMA string
C O L UM N A M E DATAT Y P E
TABLE_NAME string
COLUMN_NAME string
COLUMN_GUID Guid
COLUMN_PROPID Int64
ORDINAL_POSITION Int64
COLUMN_HASDEFAULT Boolean
COLUMN_DEFAULT string
COLUMN_FLAGS Int64
IS_NULLABLE Boolean
DATA_TYPE Int32
TYPE_GUID Guid
CHARACTER_MAXIMUM_LENGTH Int64
CHARACTER_OCTET_LENGTH Int64
NUMERIC_PRECISION Int32
NUMERIC_SCALE Int16
DATETIME_PRECISION Int64
CHARACTER_SET_CATALOG string
CHARACTER_SET_SCHEMA string
CHARACTER_SET_NAME string
COLLATION_CATALOG string
COLLATION_SCHEMA string
COLLATION_NAME string
DOMAIN_CATALOG string
DOMAIN_SCHEMA string
DOMAIN_NAME string
C O L UM N A M E DATAT Y P E
DESCRIPTION string
COLUMN_LCID Int32
COLUMN_COMPFLAGS Int32
COLUMN_SORTID Int32
COLUMN_TDSCOLLATION Byte[]
IS_COMPUTED Boolean
Procedimientos
C O L UM N A M E DATAT Y P E
PROCEDURE_CATALOG string
PROCEDURE_SCHEMA string
PROCEDURE_NAME string
PROCEDURE_TYPE Int16
PROCEDURE_DEFINITION string
DESCRIPTION string
DATE_CREATED DateTime
DATE_MODIFIED DateTime
ProcedureParameters
C O L UM N A M E DATAT Y P E
PROCEDURE_CATALOG string
PROCEDURE_SCHEMA string
PROCEDURE_NAME string
PARAMETER_NAME string
ORDINAL_POSITION Int32
PARAMETER_TYPE Int32
PARAMETER_HASDEFAULT Boolean
PARAMETER_DEFAULT string
C O L UM N A M E DATAT Y P E
IS_NULLABLE Boolean
DATA_TYPE Int32
CHARACTER_MAXIMUM_LENGTH Int64
CHARACTER_OCTET_LENGTH Int64
NUMERIC_PRECISION Int32
NUMERIC_SCALE Int16
DESCRIPTION string
TYPE_NAME string
LOCAL_TYPE_NAME string
Catálogo
C O L UM N A M E DATAT Y P E
CATALOG_NAME string
DESCRIPTION string
Índices
C O L UM N A M E DATAT Y P E
TABLE_CATALOG string
TABLE_SCHEMA string
TABLE_NAME string
INDEX_CATALOG string
INDEX_SCHEMA string
INDEX_NAME string
PRIMARY_KEY Boolean
UNIQUE Boolean
CLUSTERED Boolean
TYPE Int32
FILL_FACTOR Int32
C O L UM N A M E DATAT Y P E
INITIAL_SIZE Int32
NULLS Int32
SORT_BOOKMARKS Boolean
AUTO_UPDATE Boolean
NULL_COLLATION Int32
ORDINAL_POSITION Int64
COLUMN_NAME string
COLUMN_GUID Guid
COLUMN_PROPID Int64
COLLATION Int16
CARDINALITY Decimal
PAGES Int32
FILTER_CONDITION string
INTEGRATED Boolean
TABLE_CATALOG string
C O L UM N A M E DATAT Y P E
TABLE_SCHEMA string
TABLE_NAME string
TABLE_TYPE string
TABLE_GUID Guid
DESCRIPTION string
TABLE_PROPID Int64
DATE_CREATED DateTime
DATE_MODIFIED DateTime
Columnas
C O L UM N A M E DATAT Y P E
TABLE_CATALOG string
TABLE_SCHEMA string
TABLE_NAME string
COLUMN_NAME string
COLUMN_GUID Guid
COLUMN_PROPID Int64
ORDINAL_POSITION Int64
COLUMN_HASDEFAULT Boolean
COLUMN_DEFAULT string
COLUMN_FLAGS Int64
IS_NULLABLE Boolean
DATA_TYPE Int32
TYPE_GUID Guid
CHARACTER_MAXIMUM_LENGTH Int64
CHARACTER_OCTET_LENGTH Int64
C O L UM N A M E DATAT Y P E
NUMERIC_PRECISION Int32
NUMERIC_SCALE Int16
DATETIME_PRECISION Int64
CHARACTER_SET_CATALOG string
CHARACTER_SET_SCHEMA string
CHARACTER_SET_NAME string
COLLATION_CATALOG string
COLLATION_SCHEMA string
COLLATION_NAME string
DOMAIN_CATALOG string
DOMAIN_SCHEMA string
DOMAIN_NAME string
DESCRIPTION string
Procedimientos
C O L UM N A M E DATAT Y P E
PROCEDURE_CATALOG string
PROCEDURE_SCHEMA string
PROCEDURE_NAME string
PROCEDURE_TYPE Int16
PROCEDURE_DEFINITION string
DESCRIPTION string
DATE_CREATED DateTime
DATE_MODIFIED DateTime
ProcedureColumns
C O L UM N A M E DATAT Y P E
PROCEDURE_CATALOG string
C O L UM N A M E DATAT Y P E
PROCEDURE_SCHEMA string
PROCEDURE_NAME string
COLUMN_NAME string
COLUMN_GUID Guid
COLUMN_PROPID Int64
ROWSET_NUMBER Int64
ORDINAL_POSITION Int64
IS_NULLABLE Boolean
DATA_TYPE Int32
TYPE_GUID Guid
CHARACTER_MAXIMUM_LENGTH Int64
CHARACTER_OCTET_LENGTH Int64
NUMERIC_PRECISION Int32
NUMERIC_SCALE Int16
DESCRIPTION string
OVERLOAD Int16
Vistas
C O L UM N A M E DATAT Y P E
TABLE_CATALOG string
TABLE_SCHEMA string
TABLE_NAME string
VIEW_DEFINITION string
CHECK_OPTION Boolean
IS_UPDATABLE Boolean
DESCRIPTION string
C O L UM N A M E DATAT Y P E
DATE_CREATED DateTime
DATE_MODIFIED DateTime
Índices
C O L UM N A M E DATAT Y P E
TABLE_CATALOG string
TABLE_SCHEMA string
TABLE_NAME string
INDEX_CATALOG string
INDEX_SCHEMA string
INDEX_NAME string
PRIMARY_KEY Boolean
UNIQUE Boolean
CLUSTERED Boolean
TYPE Int32
FILL_FACTOR Int32
INITIAL_SIZE Int32
NULLS Int32
SORT_BOOKMARKS Boolean
AUTO_UPDATE Boolean
NULL_COLLATION Int32
ORDINAL_POSITION Int64
COLUMN_NAME string
COLUMN_GUID Guid
COLUMN_PROPID Int64
COLLATION Int16
C O L UM N A M E DATAT Y P E
CARDINALITY Decimal
PAGES Int32
FILTER_CONDITION string
INTEGRATED Boolean
TABLE_CATALOG string
TABLE_SCHEMA string
TABLE_NAME string
TABLE_TYPE string
TABLE_GUID Guid
DESCRIPTION string
TABLE_PROPID Int64
DATE_CREATED DateTime
DATE_MODIFIED DateTime
Columnas
C O L UM N A M E DATAT Y P E
TABLE_CATALOG string
TABLE_SCHEMA string
C O L UM N A M E DATAT Y P E
TABLE_NAME string
COLUMN_NAME string
COLUMN_GUID Guid
COLUMN_PROPID Int64
ORDINAL_POSITION Int64
COLUMN_HASDEFAULT Boolean
COLUMN_DEFAULT string
COLUMN_FLAGS Int64
IS_NULLABLE Boolean
DATA_TYPE Int32
TYPE_GUID Guid
CHARACTER_MAXIMUM_LENGTH Int64
CHARACTER_OCTET_LENGTH Int64
NUMERIC_PRECISION Int32
NUMERIC_SCALE Int16
DATETIME_PRECISION Int64
CHARACTER_SET_CATALOG string
CHARACTER_SET_SCHEMA string
CHARACTER_SET_NAME string
COLLATION_CATALOG string
COLLATION_SCHEMA string
COLLATION_NAME string
DOMAIN_CATALOG string
DOMAIN_SCHEMA string
DOMAIN_NAME string
C O L UM N A M E DATAT Y P E
DESCRIPTION string
Procedimientos
C O L UM N A M E DATAT Y P E
PROCEDURE_CATALOG string
PROCEDURE_SCHEMA string
PROCEDURE_NAME string
PROCEDURE_TYPE Int16
PROCEDURE_DEFINITION string
DESCRIPTION string
DATE_CREATED DateTime
DATE_MODIFIED DateTime
Vistas
C O L UM N A M E DATAT Y P E
TABLE_CATALOG string
TABLE_SCHEMA string
TABLE_NAME string
VIEW_DEFINITION string
CHECK_OPTION Boolean
IS_UPDATABLE Boolean
DESCRIPTION string
DATE_CREATED DateTime
DATE_MODIFIED DateTime
Índices
C O L UM N A M E DATAT Y P E
TABLE_CATALOG string
TABLE_SCHEMA string
C O L UM N A M E DATAT Y P E
TABLE_NAME string
INDEX_CATALOG string
INDEX_SCHEMA string
INDEX_NAME string
PRIMARY_KEY Boolean
UNIQUE Boolean
CLUSTERED Boolean
TYPE Int32
FILL_FACTOR Int32
INITIAL_SIZE Int32
NULLS Int32
SORT_BOOKMARKS Boolean
AUTO_UPDATE Boolean
NULL_COLLATION Int32
ORDINAL_POSITION Int64
COLUMN_NAME string
COLUMN_GUID Guid
COLUMN_PROPID Int64
COLLATION Int16
CARDINALITY Decimal
PAGES Int32
FILTER_CONDITION string
INTEGRATED Boolean
Vea también
Información general sobre ADO.NET
Objetos DbProviderFactory
23/10/2019 • 2 minutes to read • Edit Online
En esta sección
Información general sobre el modelo de fábrica
Proporciona una introducción al patrón de diseño de generadores y a la interfaz de programación.
Obtención de un objeto DbProviderFactory
Muestra cómo enumerar los proveedores de datos instalados y cómo crear una clase DbConnection a partir de
DbProviderFactory .
Vea también
Recuperar y modificar datos en ADO.NET
Información general sobre ADO.NET
Información general sobre el modelo de fábrica
08/01/2020 • 2 minutes to read • Edit Online
ADO.NET 2.0 incorporó nuevas clases base en el espacio de nombres System.Data.Common. No se pueden crear
instancias directamente de las clases base debido a que son abstractas. Entre ellas se incluyen DbConnection,
DbCommand y DbDataAdapter, y las utilizan los proveedores de datos .NET Framework como
System.Data.SqlClient y System.Data.OleDb. El aumento de clases base simplifica la agregación de funcionalidades
a los proveedores de datos .NET Framework sin necesidad de crear nuevas interfaces.
ADO.NET 2.0 incorporó también clases base abstractas, con permiten al desarrollador escribir código de acceso a
datos genérico que no dependa de un proveedor de datos concreto.
Vea también
Obtención de un objeto DbProviderFactory
DbConnection, DbCommand y DbException
Modificación de datos con un objeto DbDataAdapter
Información general sobre ADO.NET
Obtener un objeto DbProviderFactory
21/03/2020 • 9 minutes to read • Edit Online
El proceso de obtención de DbProviderFactory implica pasar información sobre un proveedor de datos a la clase
DbProviderFactories. En función de esta información, el método GetFactory crea un generador del proveedor
fuertemente tipado. Por ejemplo, para crear SqlClientFactory, se puede pasar a GetFactory una cadena con el
nombre de proveedor especificado como "System.Data.SqlClient". La otra sobrecarga de GetFactory toma
DataRow. Una vez creado el generador del proveedor, se pueden utilizar sus métodos para crear objetos
adicionales. Entre los métodos de SqlClientFactory se incluyen CreateConnection, CreateCommand y
CreateDataAdapter.
NOTE
Las clases OracleClientFactory, OdbcFactory y OleDbFactory de .NET Framework también proporcionan una funcionalidad
similar.
Registrar DbProviderFactories
Cada proveedor de datos de .NET Framework que admite una clase basada en fábrica registra información de
configuración en la sección DbProviderFactories del archivo machine.config del equipo local. El siguiente
fragmento del archivo de configuración muestra la sintaxis y formato de System.Data.SqlClient.
<system.data>
<DbProviderFactories>
<add name="SqlClient Data Provider"
invariant="System.Data.SqlClient"
description=".Net Framework Data Provider for SqlServer"
type="System.Data.SqlClient.SqlClientFactory, System.Data,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
/>
</DbProviderFactories>
</system.data>
El atributo invariable identifica el proveedor de datos subyacente. Esta sintaxis de nomenclatura en tres partes
también se utiliza al crear un nuevo generador y para identificar al proveedor en un archivo de configuración de la
aplicación, de manera que el nombre de proveedor, junto con sus cadenas de conexión asociadas, se puedan
recuperar en tiempo de conexión.
Este se puede utilizar para permitir a un usuario seleccionar un DataRow en tiempo de ejecución. El
DataTable
DataRow seleccionado se puede pasar al método GetFactory para crear un DbProviderFactory fuertemente tipado.
Un DataRow seleccionado se puede pasar al método GetFactory para crear el objeto DbProviderFactory deseado.
Return table
End Function
<configuration>
<connectionStrings>
<clear/>
<add name="NorthwindSQL"
providerName="System.Data.SqlClient"
connectionString=
"Data Source=MSSQL1;Initial Catalog=Northwind;Integrated Security=true"
/>
<add name="NorthwindAccess"
providerName="System.Data.OleDb"
connectionString=
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Data\Northwind.mdb;"
/>
</connectionStrings>
</configuration>
Return returnValue
End Function
connection = factory.CreateConnection();
connection.ConnectionString = connectionString;
}
catch (Exception ex)
{
// Set the connection to null if it was created.
if (connection != null)
{
connection = null;
}
Console.WriteLine(ex.Message);
}
}
// Return the connection.
return connection;
}
' Given a provider, create a DbProviderFactory and DbConnection.
' Returns a DbConnection on success; Nothing on failure.
Private Shared Function CreateDbConnection( _
ByVal providerName As String, ByVal connectionString As String) _
As DbConnection
connection = factory.CreateConnection()
connection.ConnectionString = connectionString
Catch ex As Exception
' Set the connection to Nothing if it was created.
If Not connection Is Nothing Then
connection = Nothing
End If
Console.WriteLine(ex.Message)
End Try
End If
Consulte también
Objetos DbProviderFactory
Cadenas de conexión
Utilizar las clases Configuration
Información general de ADO.NET
DbConnection, DbCommand y DbException
23/10/2019 • 5 minutes to read • Edit Online
Después de crear un objeto DbProviderFactory y un objeto DbConnection, puede trabajar con comandos y
lectores de datos para recuperar datos del origen de datos.
Catch ex As Exception
Console.WriteLine("Exception.Message: {0}", ex.Message)
End Try
End Using
Else
Console.WriteLine("Failed: DbConnection is Nothing.")
End If
End Sub
Try
' Do work here.
Catch ex As DbException
' Display information about the exception.
Console.WriteLine("GetType: {0}", ex.GetType())
Console.WriteLine("Source: {0}", ex.Source)
Console.WriteLine("ErrorCode: {0}", ex.ErrorCode)
Console.WriteLine("Message: {0}", ex.Message)
Finally
' Perform cleanup here.
End Try
try
{
// Do work here.
}
catch (DbException ex)
{
// Display information about the exception.
Console.WriteLine("GetType: {0}", ex.GetType());
Console.WriteLine("Source: {0}", ex.Source);
Console.WriteLine("ErrorCode: {0}", ex.ErrorCode);
Console.WriteLine("Message: {0}", ex.Message);
}
finally
{
// Perform cleanup here.
}
Vea también
Objetos DbProviderFactory
Obtención de un objeto DbProviderFactory
Modificación de datos con un objeto DbDataAdapter
Información general sobre ADO.NET
Modificar datos con un objeto DbDataAdapter
23/10/2019 • 7 minutes to read • Edit Online
using (connection)
{
// Define the query.
string queryString =
"SELECT CategoryName FROM Categories";
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Sub
using (connection)
{
// Define the query.
string queryString =
"SELECT CustomerID, CompanyName FROM Customers";
adapter.Update(table);
adapter.Update(table);
// Delete a row.
DataRow[] deleteRow = table.Select("CustomerID = 'XYZZZ'");
foreach (DataRow row in deleteRow)
{
row.Delete();
}
adapter.Update(table);
Using connection
' Define the query.
Dim queryString As String = _
"SELECT CustomerID, CompanyName FROM Customers"
adapter.Update(table)
adapter.Update(table)
adapter.Update(table)
table.AcceptChanges()
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Sub
Control de parámetros
Los proveedores de datos .NET Framework administran la asignación de nombres y la especificación de
parámetros y marcadores de posición de parámetros de diferente forma. Esta sintaxis se adapta a un origen de
datos específico, como se describe en la tabla siguiente.
El modelo de generador no es útil para la creación de objetos DbCommand y DbDataAdapter con parámetros. Es
necesario bifurcar en el código para crear parámetros que se adapten al proveedor de datos.
IMPORTANT
Por razones de seguridad, no es recomendable evitar totalmente parámetros específicos del proveedor mediante el uso de
concatenación de cadenas para construir instrucciones SQL directas. El uso de cadenas de concatenación en lugar de
parámetros expone a la aplicación a ataques por inyección de SQL.
Vea también
Objetos DbProviderFactory
Obtención de un objeto DbProviderFactory
DbConnection, DbCommand y DbException
Información general sobre ADO.NET
Traza de datos en ADO.NET
05/02/2020 • 6 minutes to read • Edit Online
ADO.NET incluye la funcionalidad de seguimiento de datos integrada que admiten los proveedores de datos de
.NET para SQL Server, Oracle, OLE DB y ODBC, así como los DataSetde ADO.NET y los protocolos de red de SQL
Server.
Las llamadas API de acceso a datos de traza ayudan a diagnosticar los siguientes problemas:
Falta de coincidencia de esquemas entre el programa cliente y la base de datos.
Inoperabilidad de la base de datos o problemas con las bibliotecas de red.
SQL incorrecto, tanto si está incluido en el código como si lo ha generado una aplicación.
Lógica de programación incorrecta.
Problemas derivados de la interacción entre varios componentes de ADO.NET o entre ADO.NET y sus
propios componentes.
Para garantizar la compatibilidad entre diferentes tecnologías de traza, éste es ampliable, de manera que un
programador puede realizar un seguimiento de un problema en cualquier nivel de la pila de la aplicación. A pesar
de que el seguimiento no es una característica exclusiva de ADO.NET, los proveedores de Microsoft aprovechan la
ventaja de el seguimiento generalizada y las API de instrumental.
Para obtener más información sobre cómo establecer y configurar el seguimiento administrado en ADO.NET, vea
seguimiento de acceso a datos.
ClientConnectionID está disponible para un objeto SqlConnection que establezca correctamente una conexión. Si
se produce un error en un intento de conexión, ClientConnectionID puede estar disponible a través de
SqlException.ToString .
ADO.NET también envía un identificador de actividad específico del subproceso El ID. de actividad se captura en las
sesiones de eventos extendidos si las sesiones se inician con la opción de TRACK_CAUSALITY habilitada. Para los
problemas de rendimiento con una conexión activa, puede obtener el identificador de actividad del seguimiento de
acceso a datos del cliente (campo ActivityID ) y después buscar el identificador de actividad en la salida de los
eventos extendidos. El identificador de actividad en los eventos extendidos es un GUID de 16 bytes (no es el
mismo GUID que el identificador de conexión de cliente) anexado con un número de secuencia de cuatro bytes. El
número de secuencia representa el orden de una solicitud dentro de un subproceso e indica el orden relativo del
lote y las instrucciones RPC para el subproceso. ActivityID se envía actualmente opcionalmente para
instrucciones por lotes de SQL y solicitudes RPC cuando el seguimiento de acceso a datos está habilitado y el
decimoctavo bit de la palabra de configuración de seguimiento de acceso a datos está activado.
A continuación se muestra un ejemplo que utiliza Transact-SQL para iniciar una sesión de Extended Events que se
almacenará en un búfer de anillo y registrará el ID. de actividad enviado desde un cliente en operaciones RPC y por
lotes.
Vea también
Network Tracing in the .NET Framework (Seguimiento de red en .NET Framework)
Seguimiento e instrumentación de aplicaciones
Información general sobre ADO.NET
Contadores de rendimiento de ADO.NET
21/03/2020 • 12 minutes to read • Edit Online
ADO.NET 2.0 incorporó la compatibilidad expandida para los contadores de rendimiento que incluye la
compatibilidad tanto con System.Data.SqlClient como con System.Data.OracleClient. Los contadores de
rendimiento System.Data.SqlClient que estaban disponibles en las versiones anteriores de ADO.NET están en
desuso y se han sustituido por los nuevos contadores de rendimiento que se describen aquí. Puede utilizar los
contadores de rendimiento de ADO.NET para supervisar el estado de su aplicación y los recursos de conexión que
emplea. Los contadores de rendimiento se pueden controlar con el Monitor de rendimiento de Windows pero
también se puede tener acceso a ellos mediante programación usando la clase PerformanceCounter del espacio
de nombres System.Diagnostics.
<system.diagnostics>
<switches>
<add name="ConnectionPoolPerformanceCounterDetail"
value="4"/>
</switches>
</system.diagnostics>
NOTE
En este ejemplo se utiliza la base de datos AdventureWorks de ejemplo incluida con SQL Server. Las cadenas de conexión
que se incluyen en el código de ejemplo presuponen que la base de datos está instalada y disponible en el equipo local con
el nombre de instancia SqlExpress y que se han creado inicios de sesión de SQL Server que coinciden con los
proporcionados en las cadenas de conexión. Quizá deba habilitar inicios de sesión de SQL Server si su servidor se ha
configurado usando la configuración de seguridad predeterminada, que solo admite la autenticación de Windows. Modifique
las cadenas de conexión según sea necesario para su entorno.
Ejemplo
Option Explicit On
Option Strict On
Imports System.Data.SqlClient
Imports System.Diagnostics
Imports System.Runtime.InteropServices
Class Program
connection1.Close()
Console.WriteLine("Closed the 1st Connection:")
WritePerformanceCounters()
connection2.Close()
Console.WriteLine("Closed the 2nd Connection:")
WritePerformanceCounters()
connection3.Close()
Console.WriteLine("Closed the 3rd Connection:")
WritePerformanceCounters()
connection4.Close()
Console.WriteLine("Closed the 4th Connection:")
WritePerformanceCounters()
End Sub
using System;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Runtime.InteropServices;
class Program
{
PerformanceCounter[] PerfCounters = new PerformanceCounter[10];
SqlConnection connection = new SqlConnection();
connection1.Close();
Console.WriteLine("Closed the 1st Connection:");
WritePerformanceCounters();
connection2.Close();
Console.WriteLine("Closed the 2nd Connection:");
WritePerformanceCounters();
connection3.Close();
Console.WriteLine("Closed the 3rd Connection:");
WritePerformanceCounters();
connection4.Close();
Console.WriteLine("Closed the 4th Connection:");
WritePerformanceCounters();
}
Consulte también
Conectarse a un origen de datos
Agrupación de conexiones de OLE DB, ODBC y Oracle
Contadores de rendimiento para ASP.NET
Generación de perfiles en tiempo de ejecución
Introducción a la supervisión de los umbrales de rendimiento
Información general de ADO.NET
Programación asincrónica
15/01/2020 • 20 minutes to read • Edit Online
En este tema se describe la compatibilidad con la programación asincrónica en el proveedor de datos de .NET
Framework para SQL Server (SqlClient), incluidas las mejoras realizadas para admitir la funcionalidad de
programación asincrónica que se presentó en .NET Framework 4,5.
TIP
A partir de la .NET Framework 4,5, estos métodos heredados ya no requieren Asynchronous Processing=true en la
cadena de conexión.
Al llamar a un método async no se asigna ningún subproceso adicional. Puede usar el subproceso existente de
finalización de E/S momentáneamente al final.
Los métodos siguientes se agregaron en .NET Framework 4,5 para admitir la programación asincrónica:
DbConnection.OpenAsync
DbCommand.ExecuteDbDataReaderAsync
DbCommand.ExecuteNonQueryAsync
DbCommand.ExecuteReaderAsync
DbCommand.ExecuteScalarAsync
GetFieldValueAsync
IsDBNullAsync
DbDataReader.NextResultAsync
DbDataReader.ReadAsync
SqlConnection.OpenAsync
SqlCommand.ExecuteNonQueryAsync
SqlCommand.ExecuteReaderAsync
SqlCommand.ExecuteScalarAsync
SqlCommand.ExecuteXmlReaderAsync
SqlDataReader.NextResultAsync
SqlDataReader.ReadAsync
SqlBulkCopy.WriteToServerAsync
Se agregaron otros miembros asincrónicos para admitir la compatibilidad con el streaming de SqlClient.
TIP
Los nuevos métodos asincrónicos no requieren Asynchronous Processing=true en la cadena de conexión.
using System;
using System.Data.SqlClient;
using System.Threading.Tasks;
class A {
Agregar la nueva característica asincrónica en una aplicación existente (combinación de patrones antiguos y
nuevos)
También es posible agregar la nueva función asincrónica (SqlConnection::OpenAsync) sin modificar la lógica
asincrónica existente. Por ejemplo, si una aplicación usa actualmente:
Puede empezar a usar el nuevo patrón asincrónico sin cambiar sustancialmente el algoritmo existente.
using System;
using System.Data.SqlClient;
using System.Threading.Tasks;
class A {
static void ProductList(IAsyncResult result) { }
class A {
static async Task PerformDBOperationsUsingProviderModel(string connectionString, string providerName) {
DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);
using (DbConnection connection = factory.CreateConnection()) {
connection.ConnectionString = connectionString;
await connection.OpenAsync();
class Program {
static void Main() {
string connectionString =
"Persist Security Info=False;Integrated Security=SSPI;database=Northwind;server=(local)";
Task task = ExecuteSqlTransaction(connectionString);
task.Wait();
}
try {
command.CommandText =
"Insert into Region (RegionID, RegionDescription) VALUES (555, 'Description')";
await command.ExecuteNonQueryAsync();
command.CommandText =
"Insert into Region (RegionID, RegionDescription) VALUES (556, 'Description')";
await command.ExecuteNonQueryAsync();
using System;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Transactions;
class Program {
public static void Main()
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
// replace these with your own values
builder.DataSource = "your_server";
builder.InitialCatalog = "your_data_source";
builder.IntegratedSecurity = true;
await connection2.OpenAsync();
connection2.EnlistTransaction(transaction);
try {
SqlCommand command1 = connection1.CreateCommand();
command1.CommandText = "Insert into RegionTable1 (RegionID, RegionDescription) VALUES (100,
'Description')";
await command1.ExecuteNonQueryAsync();
transaction.Commit();
}
catch (Exception ex) {
Console.WriteLine("Exception Type: {0}", ex.GetType());
Console.WriteLine(" Message: {0}", ex.Message);
try {
transaction.Rollback();
}
catch (Exception ex2) {
Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
Console.WriteLine(" Message: {0}", ex2.Message);
}
}
}
}
}
}
namespace Samples {
class CancellationSample {
public static void Main(string[] args) {
CancellationTokenSource source = new CancellationTokenSource();
source.CancelAfter(2000); // give up after 2 seconds
try {
Task result = CancellingAsynchronousOperations(source.Token);
result.Wait();
}
catch (AggregateException exception) {
if (exception.InnerException is SqlException) {
Console.WriteLine("Operation canceled");
}
else {
throw;
}
}
}
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Odbc;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SqlBulkCopyAsyncCodeSample {
class Program {
static string selectStatement = "SELECT * FROM [pubs].[dbo].[titles]";
static string createDestTableStatement =
@"CREATE TABLE {0} (
[title_id] [varchar](6) NOT NULL,
[title] [varchar](80) NOT NULL,
[type] [char](12) NOT NULL,
[pub_id] [char](4) NULL,
[price] [money] NULL,
[advance] [money] NULL,
[royalty] [int] NULL,
[ytd_sales] [int] NULL,
[notes] [varchar](200) NULL,
[pubdate] [datetime] NOT NULL)";
// Replace the connection string if needed, for instance to connect to SQL Express: @"Server=
(local)\SQLEXPRESS;Database=Demo;Integrated Security=true"
// static string connectionString = @"Server=(localdb)\V11.0;Database=Demo";
static string connectionString = @"Server=(local);Database=Demo;Integrated Security=true";
// Replace the Server name with your actual sql azure server name and User ID/Password
static string azureConnectionString = @"Server=SqlAzure;User
ID=myUserID;Password=myPassword;Database=Demo";
// 3.2 Add new Async.NET capabilities in an existing application (Mixing synchronous and asynchronous
calls)
private static async Task MixSyncAsyncSqlBulkCopy() {
using (OdbcConnection odbcconn = new OdbcConnection(odbcConnectionString)) {
odbcconn.Open();
using (OdbcCommand odbccmd = new OdbcCommand(selectStatement, odbcconn)) {
using (OdbcDataReader odbcreader = odbccmd.ExecuteReader()) {
using (SqlConnection conn = new SqlConnection(connectionString)) {
await conn.OpenAsync();
string temptable = "temptable";//"[#" + Guid.NewGuid().ToString("N") + "]";
SqlCommand createCmd = new SqlCommand(string.Format(createDestTableStatement, temptable),
conn);
await createCmd.ExecuteNonQueryAsync();
using (SqlBulkCopy bcp = new SqlBulkCopy(conn)) {
bcp.DestinationTableName = temptable;
await bcp.WriteToServerAsync(odbcreader);
}
}
}
}
}
}
// 3.5 Copying data from SQL Server to SQL Azure in .NET 4.5
//private static async Task AsyncSqlBulkCopySqlServerToSqlAzure() {
// using (SqlConnection srcConn = new SqlConnection(connectionString))
// using (SqlConnection destConn = new SqlConnection(azureConnectionString)) {
// await srcConn.OpenAsync();
// await destConn.OpenAsync();
// using (SqlCommand srcCmd = new SqlCommand(selectStatement, srcConn)) {
// using (SqlDataReader reader = await srcCmd.ExecuteReaderAsync()) {
// string temptable = "[#" + Guid.NewGuid().ToString("N") + "]";
// using (SqlCommand destCmd = new SqlCommand(string.Format(createDestTableStatement,
temptable), destConn)) {
// await destCmd.ExecuteNonQueryAsync();
// using (SqlBulkCopy bcp = new SqlBulkCopy(destConn)) {
// bcp.DestinationTableName = temptable;
// await bcp.WriteToServerAsync(reader);
// }
// }
// }
// }
// }
//}
NOTE
En el siguiente ejemplo se usa la base de datos de ejemplo AdventureWorks que se incluye con SQL Server. La cadena de
conexión proporcionada en el código de ejemplo asume que la base de datos está instalada y disponible en el equipo local.
Modifique la cadena de conexión según sea necesario para su entorno.
using System;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;
class Class1 {
static void Main() {
Task task = MultipleCommands();
task.Wait();
}
int vendorID;
SqlDataReader productReader = null;
string vendorSQL =
"SELECT VendorId, Name FROM Purchasing.Vendor";
string productSQL =
"SELECT Production.Product.Name FROM Production.Product " +
"INNER JOIN Purchasing.ProductVendor " +
"ON Production.Product.ProductID = " +
"Purchasing.ProductVendor.ProductID " +
"WHERE Purchasing.ProductVendor.VendorID = @VendorId";
productCmd.Parameters.Add("@VendorId", SqlDbType.Int);
await awConnection.OpenAsync();
using (SqlDataReader vendorReader = await vendorCmd.ExecuteReaderAsync()) {
while (await vendorReader.ReadAsync()) {
Console.WriteLine(vendorReader["Name"]);
vendorID = (int)vendorReader["VendorId"];
productCmd.Parameters["@VendorId"].Value = vendorID;
// The following line of code requires a MARS-enabled connection.
productReader = await productCmd.ExecuteReaderAsync();
using (productReader) {
while (await productReader.ReadAsync()) {
Console.WriteLine(" " +
productReader["Name"].ToString());
}
}
}
}
}
}
NOTE
En el siguiente ejemplo se usa la base de datos de ejemplo AdventureWorks que se incluye con SQL Server. La cadena de
conexión proporcionada en el código de ejemplo asume que la base de datos está instalada y disponible en el equipo local.
Modifique la cadena de conexión según sea necesario para su entorno.
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;
class Program {
static void Main() {
Task task = ReadingAndUpdatingData();
task.Wait();
}
int vendorID = 0;
int productID = 0;
int minOrderQty = 0;
int maxOrderQty = 0;
int onOrderQty = 0;
int recordsUpdated = 0;
int totalRecordsUpdated = 0;
string vendorSQL =
"SELECT VendorID, Name FROM Purchasing.Vendor " +
"WHERE CreditRating = 5";
string prodVendSQL =
"SELECT ProductID, MaxOrderQty, MinOrderQty, OnOrderQty " +
"FROM Purchasing.ProductVendor " +
"WHERE VendorID = @VendorID";
"WHERE VendorID = @VendorID";
string updateSQL =
"UPDATE Purchasing.ProductVendor " +
"SET OnOrderQty = @OrderQty " +
"WHERE ProductID = @ProductID AND VendorID = @VendorID";
vendorID = (int)vendorReader["VendorID"];
prodVendCmd.Parameters["@VendorID"].Value = vendorID;
prodVendReader = await prodVendCmd.ExecuteReaderAsync();
using (prodVendReader) {
while (await prodVendReader.ReadAsync()) {
productID = (int)prodVendReader["ProductID"];
if (prodVendReader["OnOrderQty"] == DBNull.Value) {
minOrderQty = (int)prodVendReader["MinOrderQty"];
onOrderQty = minOrderQty;
}
else {
maxOrderQty = (int)prodVendReader["MaxOrderQty"];
onOrderQty = (int)(maxOrderQty / 2);
}
updateCmd.Parameters["@OrderQty"].Value = onOrderQty;
updateCmd.Parameters["@ProductID"].Value = productID;
updateCmd.Parameters["@VendorID"].Value = vendorID;
La compatibilidad de streaming entre SQL Server y una aplicación (novedad en .NET Framework 4,5) admite datos
no estructurados en el servidor (documentos, imágenes y archivos multimedia). Una base de datos de SQL Server
puede almacenar objetos binarios grandes (blobs), pero la recuperación de blobs puede utilizar mucha memoria.
La compatibilidad con streaming hacia y desde SQL Server simplifica la escritura de aplicaciones que transmiten
datos, sin tener que cargar completamente los datos en la memoria, lo que da lugar a menos excepciones de
desbordamiento de memoria.
La compatibilidad con streaming también permitirá que las aplicaciones de nivel intermedio escalen mejor,
especialmente en escenarios donde los objetos comerciales establezcan conexión con SQL Azure para enviar,
recuperar y manipular BLOB grandes.
WARNING
Las llamadas asincrónicas no se admiten si una aplicación también usa la palabra clave de cadena de conexión
Context Connection .
Los miembros agregados para admitir streaming se usan para recuperar datos de consultas y para pasar parámetros a
consultas y procedimientos almacenados. La característica de streaming está dirigida a escenarios OLTP y de migración de
datos básicos, y es aplicable en entornos de migración de datos locales y remotos.
using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Threading.Tasks;
using System.Xml;
namespace StreamingFromServer {
class Program {
// Replace the connection string if needed, for instance to connect to SQL Express: @"Server=
(local)\SQLEXPRESS;Database=Demo;Integrated Security=true"
private const string connectionString = @"Server=(localdb)\V11.0;Database=Demo";
Console.WriteLine("Done");
}
// Application retrieving a large BLOB from SQL Server in .NET 4.5 using the new asynchronous
capability
private static async Task CopyBinaryValueToFile() {
string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
"binarydata.bin");
// The reader needs to be executed with the SequentialAccess behavior to enable network
streaming
// Otherwise ReadAsync will buffer the entire BLOB into memory which can cause scalability
issues or even OutOfMemoryExceptions
using (SqlDataReader reader = await
command.ExecuteReaderAsync(CommandBehavior.SequentialAccess)) {
if (await reader.ReadAsync()) {
if (!(await reader.IsDBNullAsync(0))) {
using (FileStream file = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
using (Stream data = reader.GetStream(0)) {
// Asynchronously copy the stream from the server to the file we just created
await data.CopyToAsync(file);
}
}
}
}
}
}
}
}
// Application transferring a large Text File from SQL Server in .NET 4.5
private static async Task PrintTextValues() {
using (SqlConnection connection = new SqlConnection(connectionString)) {
await connection.OpenAsync();
using (SqlCommand command = new SqlCommand("SELECT [id], [textdata] FROM [Streams]", connection))
{
// The reader needs to be executed with the SequentialAccess behavior to enable network
// The reader needs to be executed with the SequentialAccess behavior to enable network
streaming
// Otherwise ReadAsync will buffer the entire text document into memory which can cause
scalability issues or even OutOfMemoryExceptions
using (SqlDataReader reader = await
command.ExecuteReaderAsync(CommandBehavior.SequentialAccess)) {
while (await reader.ReadAsync()) {
Console.Write("{0}: ", reader.GetInt32(0));
if (await reader.IsDBNullAsync(1)) {
Console.Write("(NULL)");
}
else {
char[] buffer = new char[4096];
int charsRead = 0;
using (TextReader data = reader.GetTextReader(1)) {
do {
// Grab each chunk of text and write it to the console
// If you are writing to a TextWriter you should use WriteAsync or
WriteLineAsync
charsRead = await data.ReadAsync(buffer, 0, buffer.Length);
Console.Write(buffer, 0, charsRead);
} while (charsRead > 0);
}
}
Console.WriteLine();
}
}
}
}
}
// Application transferring a large Xml Document from SQL Server in .NET 4.5
private static async Task PrintXmlValues() {
using (SqlConnection connection = new SqlConnection(connectionString)) {
await connection.OpenAsync();
using (SqlCommand command = new SqlCommand("SELECT [id], [xmldata] FROM [Streams]", connection))
{
// The reader needs to be executed with the SequentialAccess behavior to enable network
streaming
// Otherwise ReadAsync will buffer the entire Xml Document into memory which can cause
scalability issues or even OutOfMemoryExceptions
using (SqlDataReader reader = await
command.ExecuteReaderAsync(CommandBehavior.SequentialAccess)) {
while (await reader.ReadAsync()) {
Console.WriteLine("{0}: ", reader.GetInt32(0));
if (await reader.IsDBNullAsync(1)) {
Console.WriteLine("\t(NULL)");
}
else {
using (XmlReader xmlReader = reader.GetXmlReader(1)) {
int depth = 1;
// NOTE: The XmlReader returned by GetXmlReader does NOT support async operations
// See the example below (PrintXmlValuesViaNVarChar) for how to get an XmlReader
with asynchronous capabilities
while (xmlReader.Read()) {
switch (xmlReader.NodeType) {
case XmlNodeType.Element:
Console.WriteLine("{0}<{1}>", new string('\t', depth), xmlReader.Name);
depth++;
break;
case XmlNodeType.Text:
Console.WriteLine("{0}{1}", new string('\t', depth), xmlReader.Value);
break;
case XmlNodeType.EndElement:
depth--;
Console.WriteLine("{0}</{1}>", new string('\t', depth), xmlReader.Name);
Console.WriteLine("{0}</{1}>", new string('\t', depth), xmlReader.Name);
break;
}
}
}
}
}
}
}
}
}
// Application transferring a large Xml Document from SQL Server in .NET 4.5
// This goes via NVarChar and TextReader to enable asynchronous reading
private static async Task PrintXmlValuesViaNVarChar() {
XmlReaderSettings xmlSettings = new XmlReaderSettings() {
// Async must be explicitly enabled in the XmlReaderSettings otherwise the XmlReader will throw
exceptions when async methods are called
Async = true,
// Since we will immediately wrap the TextReader we are creating in an XmlReader, we will permit
the XmlReader to take care of closing\disposing it
CloseInput = true,
// If the Xml you are reading is not a valid document (as per
<https://docs.microsoft.com/previous-versions/dotnet/netframework-4.0/6bts1x50(v=vs.100)>) you will need to
set the conformance level to Fragment
ConformanceLevel = ConformanceLevel.Fragment
};
// Cast the XML into NVarChar to enable GetTextReader - trying to use GetTextReader on an XML
type will throw an exception
using (SqlCommand command = new SqlCommand("SELECT [id], CAST([xmldata] AS NVARCHAR(MAX)) FROM
[Streams]", connection)) {
// The reader needs to be executed with the SequentialAccess behavior to enable network
streaming
// Otherwise ReadAsync will buffer the entire Xml Document into memory which can cause
scalability issues or even OutOfMemoryExceptions
using (SqlDataReader reader = await
command.ExecuteReaderAsync(CommandBehavior.SequentialAccess)) {
while (await reader.ReadAsync()) {
Console.WriteLine("{0}:", reader.GetInt32(0));
if (await reader.IsDBNullAsync(1)) {
Console.WriteLine("\t(NULL)");
}
else {
// Grab the row as a TextReader, then create an XmlReader on top of it
// We are not keeping a reference to the TextReader since the XmlReader is created
with the "CloseInput" setting (so it will close the TextReader when needed)
using (XmlReader xmlReader = XmlReader.Create(reader.GetTextReader(1), xmlSettings))
{
int depth = 1;
// The XmlReader above now supports asynchronous operations, so we can use
ReadAsync here
while (await xmlReader.ReadAsync()) {
switch (xmlReader.NodeType) {
case XmlNodeType.Element:
Console.WriteLine("{0}<{1}>", new string('\t', depth), xmlReader.Name);
depth++;
break;
case XmlNodeType.Text:
// Depending on what your data looks like, you should either use Value or
GetValueAsync
// Value has less overhead (since it doesn't create a Task), but it may
also block if additional data is required
Console.WriteLine("{0}{1}", new string('\t', depth), await
xmlReader.GetValueAsync());
break;
case XmlNodeType.EndElement:
depth--;
Console.WriteLine("{0}</{1}>", new string('\t', depth), xmlReader.Name);
break;
}
}
}
}
}
}
}
}
}
}
}
using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace StreamingToServer {
class Program {
// Replace the connection string if needed, for instance to connect to SQL Express: @"Server=
(local)\SQLEXPRESS;Database=Demo2;Integrated Security=true"
(local)\SQLEXPRESS;Database=Demo2;Integrated Security=true"
private const string connectionString = @"Server=(localdb)\V11.0;Database=Demo2";
StreamBLOBToServer().Wait();
StreamTextToServer().Wait();
Console.WriteLine("Done");
}
// This is used to generate the files which are used by the other sample methods
private static void CreateDemoFiles() {
Random rand = new Random();
byte[] data = new byte[1024];
rand.NextBytes(data);
using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace StreamingFromServerToAnother {
class Program {
// Replace the connection string if needed, for instance to connect to SQL Express: @"Server=
(local)\SQLEXPRESS;Database=Demo2;Integrated Security=true"
private const string connectionString = @"Server=(localdb)\V11.0;Database=Demo2";
Console.WriteLine("Done");
}
// Streaming from one SQL Server to Another One using the new Async.NET
private static async Task E2EStream(CancellationToken cancellationToken) {
using (SqlConnection readConn = new SqlConnection(connectionString)) {
using (SqlConnection writeConn = new SqlConnection(connectionString)) {
// Note that we are using the same cancellation token for calls to both connections\commands
// Also we can start both the connection opening asynchronously, and then wait for both to
complete
Task openReadConn = readConn.OpenAsync(cancellationToken);
Task openWriteConn = writeConn.OpenAsync(cancellationToken);
await Task.WhenAll(openReadConn, openWriteConn);
// Add an empty parameter to the write command which will be used for the streams we are
copying
// Size is set to -1 to indicate "MAX"
SqlParameter streamParameter = writeCmd.Parameters.Add("@bindata", SqlDbType.Binary, -
1);
// The reader needs to be executed with the SequentialAccess behavior to enable network
streaming
// Otherwise ReadAsync will buffer the entire BLOB into memory which can cause
scalability issues or even OutOfMemoryExceptions
using (SqlDataReader reader = await
readCmd.ExecuteReaderAsync(CommandBehavior.SequentialAccess, cancellationToken)) {
while (await reader.ReadAsync(cancellationToken)) {
// Grab a stream to the binary data in the source database
using (Stream dataStream = reader.GetStream(0)) {
// Set the parameter value to the stream source that was opened
streamParameter.Value = dataStream;
Vea también
Recuperar y modificar datos en ADO.NET
LINQ to DataSet
23/10/2019 • 2 minutes to read • Edit Online
LINQ to DataSet hace que sea más fácil y rápido consultar los datos almacenados en caché DataSet en un objeto.
En concreto, LINQ to DataSet simplifica las consultas, ya que permite a los desarrolladores escribir consultas
desde el propio lenguaje de programación, en lugar de usar un lenguaje de consulta independiente. Esto es
especialmente útil para los desarrolladores de Visual Studio, que ahora pueden aprovechar las ventajas de la
comprobación de sintaxis en tiempo de compilación, los tipos estáticos y la compatibilidad con IntelliSense que
proporciona Visual Studio en sus consultas.
LINQ to DataSet también puede usarse para consultar los datos que se han consolidado de uno o varios orígenes
de datos. Esto permite muchos casos que requieren flexibilidad en la forma de representar y controlar los datos,
como consultar datos agregados localmente y almacenar en caché en el nivel medio en aplicaciones web. En
concreto, las aplicaciones de inteligencia empresaria, análisis e informes genéricos requieren este método de
manipulación.
La funcionalidad de LINQ to DataSet se expone principalmente a través de los métodos DataRowExtensions de
DataTableExtensions extensión de las clases y. LINQ to DataSet se basa en y usa la arquitectura de ADO.NET
existente y no está diseñada para reemplazar ADO.NET en el código de la aplicación. El código de ADO.NET
existente seguirá funcionando en una aplicación LINQ to DataSet. La relación de LINQ to DataSet con ADO.NET y
el almacén de datos se muestra en el diagrama siguiente.
En esta sección
Introducción
Guía de programación
Referencia
DataTableExtensions
DataRowExtensions
DataRowComparer
Vea también
Language Integrated Query (LINQ) (C#)
Language Integrated Query (LINQ) (Visual Basic)
LINQ y ADO.NET
ADO.NET
Introducción (LINQ to DataSet)
23/10/2019 • 2 minutes to read • Edit Online
En esta sección se proporciona información introductoria sobre la programación con LINQ to DataSet.
En esta sección
Información general de LINQ to DataSet
Proporciona información general conceptual de LINQ to DataSet.
Carga de datos en un conjunto de datos
Proporciona un ejemplo de llenado de DataSet. Este ejemplo utiliza DataAdapter para recuperar datos de la base
de datos.
Descargar bases de datos de ejemplo
Proporciona información sobre cómo descargar la base de datos de ejemplo AdventureWorks, que se usa en los
ejemplos de en la sección LINQ to DataSet.
Procedimientos: Creación de un proyecto de LINQ to DataSet en Visual Studio
Proporciona información sobre cómo crear un proyecto de LINQ to DataSet en Visual Studio.
Referencia
DataRowComparer
DataRowExtensions
DataTableExtensions
Vea también
LINQ y ADO.NET
Language Integrated Query (LINQ) (C#)
Language Integrated Query (LINQ) (Visual Basic)
Información general de LINQ to DataSet
08/01/2020 • 7 minutes to read • Edit Online
La DataSet es uno de los componentes más utilizados de ADO.NET. Es un elemento clave del modelo de
programación desconectado en el que se basa ADO.NET y permite almacenar explícitamente en caché los datos de
diferentes orígenes de datos. Para el nivel de presentación, DataSet está estrechamente integrado en los controles
de GUI para el enlace de datos. Para el nivel medio, proporciona una caché que conserva la forma relacional de los
datos e incluye servicios de exploración de jerarquías y consultas rápidos y sencillos. Una técnica común que se
usa para reducir el número de solicitudes en una base de datos es usar el DataSet para el almacenamiento en
caché en el nivel intermedio. Por ejemplo, considere una aplicación Web ASP.NET controlada por datos. A menudo
una parte importante de los datos de aplicación no cambia frecuentemente y es común entre sesiones o usuarios.
Estos datos se pueden conservar en memoria o en un servidor web, lo que reduce el número de solicitudes en la
base de datos y acelera las interacciones del usuario. Otro aspecto útil del DataSet es que permite que una
aplicación lleve subconjuntos de datos de uno o varios orígenes de datos al espacio de la aplicación. La aplicación
puede manipular los datos en memoria mientras retiene su forma relacional.
A pesar de su importancia, DataSet tiene capacidades de consulta limitadas. El método Select se puede usar para
filtrar y ordenar y los métodos GetChildRows y GetParentRow se pueden usar para la exploración de jerarquías. Sin
embargo, para cualquier tarea más compleja, el programador debe escribir una consulta personalizada. Esto puede
tener como resultado aplicaciones con un bajo rendimiento y con un mantenimiento difícil.
LINQ to DataSet facilita y agiliza la consulta de datos almacenados en caché en un objeto DataSet. Esas consultas
se expresan en el lenguaje de programación mismo, en lugar de como literales de cadena incrustados en el código
de la aplicación. Esto significa que los desarrolladores no tienen que aprender un lenguaje de consultas diferente.
Además, LINQ to DataSet permite a los desarrolladores de Visual Studio trabajar de forma más productiva, ya que
el IDE de Visual Studio proporciona comprobación de sintaxis en tiempo de compilación, tipos estáticos y
compatibilidad con IntelliSense para LINQ. LINQ to DataSet también puede usarse para consultar los datos que se
han consolidado de uno o varios orígenes de datos. Esto permite muchos casos que requieren flexibilidad en la
forma de representar y controlar los datos. En concreto, las aplicaciones de inteligencia empresaria, análisis e
informes genéricos requieren este método de manipulación.
Vea también
Consulta de conjuntos de datos
Language Integrated Query (LINQ) (C#)
Language Integrated Query (LINQ) (Visual Basic)
LINQ to SQL
Cargar datos en un conjunto de datos
23/10/2019 • 4 minutes to read • Edit Online
Primero DataSet se debe rellenar un objeto para poder realizar consultas sobre él con LINQ to DataSet.
Existen varias formas de rellenar DataSet. Por ejemplo, puede utilizar LINQ to SQL para consultar la base de
datos y cargar los resultados DataSeten. Para más información, vea LINQ to SQL.
Otra forma habitual de cargar datos en DataSet es utilizar la clase DataAdapter para recuperar datos desde
la base de datos. Esto se muestra en el ejemplo siguiente.
Ejemplo
En este ejemplo se utiliza DataAdapter para consultar en la base de datos AdventureWorks la información
de ventas del año 2002, y cargar los resultados en un DataSet. DataSet Una vez que se ha rellenado, puede
escribir consultas en él mediante LINQ to DataSet. El FillDataSet método de este ejemplo se usa en las
consultas de ejemplo de LINQ to DataSet ejemplos. Para obtener más información, vea consultar
conjuntosde datos.
try
{
// Create a new adapter and give it a query to fetch sales order, contact,
// address, and product information for sales in the year 2002. Point connection
// information to the configuration setting "AdventureWorks".
string connectionString = "Data Source=localhost;Initial Catalog=AdventureWorks;"
+ "Integrated Security=true;";
' Create a new adapter and give it a query to fetch sales order, contact,
' address, and product information for sales in the year 2002. Point connection
' information to the configuration setting "AdventureWorks".
Dim da = New SqlDataAdapter( _
"SELECT SalesOrderID, ContactID, OrderDate, OnlineOrderFlag, " & _
"TotalDue, SalesOrderNumber, Status, ShipToAddressID, BillToAddressID " & _
"FROM Sales.SalesOrderHeader " & _
"WHERE DATEPART(YEAR, OrderDate) = @year; " & _
"SELECT d.SalesOrderID, d.SalesOrderDetailID, d.OrderQty, " & _
"d.ProductID, d.UnitPrice " & _
"FROM Sales.SalesOrderDetail d " & _
"INNER JOIN Sales.SalesOrderHeader h " & _
"ON d.SalesOrderID = h.SalesOrderID " & _
"WHERE DATEPART(YEAR, OrderDate) = @year; " & _
"SELECT p.ProductID, p.Name, p.ProductNumber, p.MakeFlag, " & _
"p.Color, p.ListPrice, p.Size, p.Class, p.Style " & _
"FROM Production.Product p; " & _
"SELECT DISTINCT a.AddressID, a.AddressLine1, a.AddressLine2, " & _
"a.City, a.StateProvinceID, a.PostalCode " & _
"FROM Person.Address a " & _
"INNER JOIN Sales.SalesOrderHeader h " & _
"ON a.AddressID = h.ShipToAddressID OR a.AddressID = h.BillToAddressID " & _
"WHERE DATEPART(YEAR, OrderDate) = @year; " & _
"SELECT DISTINCT c.ContactID, c.Title, c.FirstName, " & _
"c.LastName, c.EmailAddress, c.Phone " & _
"FROM Person.Contact c " & _
"INNER JOIN Sales.SalesOrderHeader h " & _
"ON c.ContactID = h.ContactID " & _
"WHERE DATEPART(YEAR, OrderDate) = @year;", _
connectionString)
da.Fill(ds)
Vea también
Información general de LINQ to DataSet
Consulta de conjuntos de datos
Ejemplos de LINQ to DataSet
Descargar bases de datos de ejemplo (LINQ to
DataSet)
23/10/2019 • 5 minutes to read • Edit Online
En los ejemplos y los tutoriales de la documentación de LINQ to DataSet se usa la base de datos de ejemplo
AdventureWorks. Puede descargar este producto de forma gratuita del sitio de descarga de Microsoft. Los
ejemplos y los tutoriales de la documentación de LINQ to DataSet usan SQL Server como almacén de datos. SQL
Server Express Edition, que está disponible de forma gratuita, también se puede usar como almacén de datos en
lugar de SQL Server.
Si ha instalado esos archivos en una unidad o en un directorio diferente, debe revisar las rutas de acceso
correctamente antes de ejecutar el procedimiento almacenado sp_attach_db .
Vea también
Introducción
Cómo: crear un proyecto de LINQ to DataSet en
Visual Studio
04/12/2019 • 2 minutes to read • Edit Online
Los diferentes tipos de proyectos de LINQ requieren ciertas referencias de ensamblado y espacios de nombres
importados (Visual Basic) o mediante directivas (C#). El requisito mínimo para LINQ es una referencia a
System. Core. dll y una directiva de using para System.Linq.
Estos requisitos se proporcionan de forma predeterminada si crea un nuevo C# proyecto de aplicación de
consola en Visual Studio 2017 o una versión posterior. Si va a actualizar un proyecto de una versión anterior de
Visual Studio, es posible que tenga que proporcionar estas referencias relacionadas con LINQ de forma
manual.
LINQ to DataSet requiere dos referencias adicionales a System. Data. dll y System. Data. DataSetExtensions. dll.
NOTE
Si va a compilar desde un símbolo del sistema, debe hacer referencia manualmente a las DLL relacionadas con LINQ en
%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5.
using System.Data;
using System.Linq;
3. Opcionalmente, agregue una using Directiva (o Imports instrucción) para System. Data. Common o
System. Data. SqlClient , dependiendo de cómo se conecte a la base de datos.
Vea también
Introducción a LINQ to DataSet
Guía de programación (LINQ to DataSet)
08/01/2020 • 2 minutes to read • Edit Online
En esta sección se proporciona información conceptual y ejemplos para programar con LINQ to DataSet.
Esta sección
Consultas en LINQ to DataSet
Proporciona información sobre cómo escribir consultas de LINQ to DataSet.
Consulta de conjuntos de datos
Describe cómo consultar objetos DataSet.
Comparación de objetos DataRow
Describe cómo utilizar el objeto DataRowComparer para comparar filas de datos.
Creación de un objeto DataTable a partir de una consulta
Proporciona información sobre cómo crear un DataTable a partir de una consulta de LINQ to DataSet mediante el
método CopyToDataTable.
Cómo: implementar CopyToDataTable<T > donde el tipo genérico T no es DataRow
Describe cómo implementar un método CopyToDataTable<T> personalizado en el que el parámetro genérico T no
es de tipo DataRow.
Métodos genéricos Field y SetField
Proporciona información acerca de los métodos genéricos Field y SetField.
Enlace de datos y LINQ to DataSet
Describe el enlace de datos mediante el objeto DataView.
Depuración de consultas de LINQ to DataSet
Proporciona información sobre la depuración y solución de problemas de consultas LINQ to DataSet.
Seguridad
Describe problemas de seguridad en LINQ to DataSet.
Ejemplos de LINQ to DataSet
Proporciona ejemplos de consultas que utilizan los operadores de LINQ.
Referencia
DataRowComparer
DataRowExtensions
DataTableExtensions
DataView
Vea también
LINQ y ADO.NET
Language-Integrated Query (LINQ)
Consultas en LINQ to DataSet
08/01/2020 • 12 minutes to read • Edit Online
Una consulta es una expresión que recupera datos de un origen de datos. Las consultas se suelen expresar en un
lenguaje de consulta especializado, como SQL para bases de datos relacionales y XQuery para XML. Por lo tanto,
los programadores han tenido que aprender un lenguaje de consultas nuevo para cada tipo de origen de datos o
formato de datos que consultan. Language-Integrated Query (LINQ) ofrece un modelo coherente y más sencillo
para trabajar con los datos de varios formatos y orígenes de datos. En una consulta de LINQ siempre se trabaja
con objetos de programación.
Una operación de consulta de LINQ consta de tres acciones: obtener el origen o los orígenes de datos, crear la
consulta y ejecutar la consulta.
Los orígenes de datos que implementan la interfaz genérica IEnumerable<T> se pueden consultar a través de
LINQ. La llamada a AsEnumerable en un DataTable devuelve un objeto que implementa la interfaz genérica de
IEnumerable<T>, que actúa como origen de datos para las consultas de LINQ to DataSet.
En la consulta se especifica exactamente la información que se desea recuperar del origen de datos. Una consulta
también puede especificar cómo se debe ordenar, agrupar y conformar esa información antes de que se devuelva.
En LINQ, una consulta se almacena en una variable. Si la consulta está diseñada para devolver una secuencia de
valores, la variable misma de la consulta debe ser de tipo enumerable. Esta variable de consulta no realiza ninguna
acción y no devuelve datos; solamente almacena la información de la consulta. Tras crear una consulta debe
ejecutarla para recuperar los datos.
En una consulta que devuelve una secuencia de valores, la variable de consulta por sí misma nunca conserva los
resultados de la consulta y solo almacena los comandos de la misma. La ejecución de la consulta se aplaza hasta
que la variable de consulta se recorre en iteración en un bucle foreach o For Each . Esto se denomina ejecución
aplazada; es decir, la ejecución de la consulta se produce una vez después de la construcción de la consulta. Esto
significa que se puede ejecutar una consulta con la frecuencia que se desee. Esto es útil cuando, por ejemplo, se
tiene una base de datos que otras aplicaciones están actualizando. En su aplicación puede crear una consulta para
recuperar la información más reciente y ejecutar de forma repetida la consulta, devolviendo cada vez la
información actualizada.
A diferencia de las consultas en diferido, que devuelven una secuencia de valores, las consultas que devuelven un
valor singleton se ejecutan inmediatamente. Algunos ejemplos de consultas singleton son Count, Max, Average y
First. Se ejecutan inmediatamente porque se necesitan los resultados de la consulta para calcular el resultado
singleton. Por ejemplo, para buscar la media de los resultados de consultas, debe ejecutarse la consulta para que la
función de cálculo de media tenga datos de entrada con los que trabajar. También puede usar los métodos ToList o
ToArray en una consulta para forzar la ejecución inmediata de una consulta que no crea un valor singleton. Esas
técnicas para forzar la ejecución inmediata pueden ser útiles si desea almacenar en caché los resultados de una
consulta.
Consultas
LINQ to DataSet consultas se pueden formular en dos sintaxis diferentes: sintaxis de expresiones de consulta y
sintaxis de consulta basada en métodos.
Sintaxis de la expresión de consulta de
Las expresiones de consulta son una sintaxis de consulta declarativa. Esta sintaxis permite a un desarrollador
escribir consultas en C# o Visual Basic en un formato similar a SQL. Si se utiliza la sintaxis de expresiones de
consulta, se pueden realizar incluso operaciones complejas de filtrado, ordenación y agrupamiento en orígenes de
datos con código mínimo. Para obtener más información, vea expresiones de consulta LINQ y operaciones básicas
de consulta (Visual Basic).
El Common Language Runtime de .NET Framework (CLR) no puede leer la sintaxis de expresiones de consulta en
sí. Por lo tanto, en tiempo de compilación, las expresiones de consulta se traducen a algo que CLR no comprende:
las llamadas a métodos. Estos métodos se conocen como operadores de consulta estándar. Como programador,
tiene la opción de llamarlos directamente utilizando la sintaxis de método en lugar de la sintaxis de consulta. Para
obtener más información, vea Query Syntax and Method Syntax in LINQ (Sintaxis de consulta y sintaxis de método
en LINQ). Para obtener más información acerca de los operadores de consulta estándar, vea información general
sobre operadores de consulta estándar.
El siguiente ejemplo usa Select para devolver todas las filas de la tabla Product y mostrar los nombres de
producto.
IEnumerable<DataRow> query =
from product in products.AsEnumerable()
select product;
Console.WriteLine("Product Names:");
foreach (DataRow p in query)
{
Console.WriteLine(p.Field<string>("Name"));
}
Console.WriteLine("Product Info:");
foreach (var productInfo in query)
{
Console.WriteLine("Product name: {0} Product number: {1} List price: ${2} ",
productInfo.ProductName, productInfo.ProductNumber, productInfo.Price);
}
Console.WriteLine("Product Info:")
For Each product In query
Console.Write("Product name: " & product.ProductName)
Console.Write("Product number: " & product.ProductNumber)
Console.WriteLine("List price: $ " & product.Price)
Next
Crear consultas
Tal y como se ha mencionado anteriormente en este tema, la variable de consulta solo almacena los comandos de
la consulta cuando ésta se diseña para devolver una secuencia de valores. Si la consulta no contiene un método
que cause una ejecución inmediata, la ejecución real de la consulta se aplaza hasta que la variable de consulta se
recorra en iteración en un bucle foreach o For Each . La ejecución aplazada permite combinar varias consultas o
ampliar una consulta. Cuando se amplía una consulta, se modifica para incluir las nuevas operaciones. La ejecución
eventual reflejará los cambios. En el siguiente ejemplo, la primera consulta devuelve todos los productos. La
segunda consulta amplía la primera usando Where para devolver todos los productos del tamaño "L":
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
IEnumerable<DataRow> productsQuery =
from product in products.AsEnumerable()
select product;
IEnumerable<DataRow> largeProducts =
productsQuery.Where(p => p.Field<string>("Size") == "L");
Dim largeProducts = _
productsQuery.Where(Function(p) p.Field(Of String)("Size") = "L")
Una vez que se ha ejecutado una consulta, no se pueden crear consultas adicionales y todas las consultas
posteriores utilizarán los operadores de LINQ en memoria. La ejecución de la consulta se producirá al recorrer en
iteración la variable de consulta en una instrucción foreach o For Each , o mediante una llamada a uno de los
operadores de conversión de LINQ que causan la ejecución inmediata. Entre estos operadores se incluyen los
siguientes: ToList, ToArray, ToLookup y ToDictionary.
En el siguiente ejemplo, la primera consulta devuelve todos los productos ordenados por el precio de la lista. El
método ToArray se usa para forzar la ejecución inmediata de la consulta:
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
IEnumerable<DataRow> query =
from product in products.AsEnumerable()
orderby product.Field<Decimal>("ListPrice") descending
select product;
Dim query = _
From product In products.AsEnumerable() _
Order By product.Field(Of Decimal)("ListPrice") Descending _
Select product
Vea también
Guía de programación
Consulta de conjuntos de datos
Introducción a LINQ en C#
Introducción a LINQ en Visual Basic
Consultar conjuntos de datos (LINQ to DataSet)
08/01/2020 • 2 minutes to read • Edit Online
Después de rellenar un objeto DataSet con datos se puede empezar a realizar consultas sobre él. La formulación
de consultas con LINQ to DataSet es similar a usar Language-Integrated Query (LINQ) en otros orígenes de datos
habilitados para LINQ. No obstante, recuerde que cuando utiliza consultas LINQ sobre un objeto DataSet, está
consultando una enumeración de objetos de DataRow en lugar de una enumeración de un tipo personalizado.
Esto significa que puede usar cualquiera de los miembros de la clase DataRow en las consultas LINQ. Esto permite
crear consultas enriquecidas y complejas.
Como con otras implementaciones de LINQ, puede crear LINQ to DataSet consultas de dos formas diferentes:
sintaxis de expresiones de consulta y sintaxis de consulta basada en métodos. Puede usar la sintaxis de expresión
de consulta o la sintaxis de consulta basada en métodos para realizar consultas en tablas únicas en un DataSet, en
tablas múltiples en un DataSet o en tablas en un DataSet con tipo.
Esta sección
Consultas de tabla única
Describe cómo realizar consultas en una sola tabla.
Consultas entre tablas
Describe cómo realizar consultas entre tablas.
Consultar objetos DataSet con tipo
Describe cómo consultar objetos DataSet con tipo.
Vea también
Ejemplos de LINQ to DataSet
Carga de datos en un conjunto de datos
Consultas de tabla única (LINQ to DataSet)
27/03/2020 • 5 minutes to read • Edit Online
var query =
from order in orders.AsEnumerable()
where order.Field<bool>("OnlineOrderFlag") == true
select new
{
SalesOrderID = order.Field<int>("SalesOrderID"),
OrderDate = order.Field<DateTime>("OrderDate"),
SalesOrderNumber = order.Field<string>("SalesOrderNumber")
};
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of Boolean)("OnlineOrderFlag") = True _
Select New With { _
.SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
.OrderDate = order.Field(Of DateTime)("OrderDate"), _
.SalesOrderNumber = order.Field(Of String)("SalesOrderNumber") _
}
A continuación, el bucle foreach enumera el objeto enumerable devuelto por Select y produce los resultados de
la consulta. Dado que una consulta es un tipo Enumerable, que implementa IEnumerable<T>, la evaluación de la
consulta se difiere hasta que se procesa una iteración en la variable de la consulta mediante el bucle foreach . La
evaluación de la consulta en diferido permite que éstas se mantengan como valores que se pueden evaluar varias
veces, y cada vez produciendo resultados potencialmente diferentes.
El método Field proporciona acceso a los valores de columna de DataRow y SetField (que no se mostraba en el
ejemplo anterior) establece los valores de columna en DataRow. Tanto Field el SetField método como el método
controlan los tipos de valor que aceptan valores NULL, por lo que no es necesario comprobar explícitamente si hay
valores NULL. Además, ambos son métodos genéricos, lo que significa que no es necesario convertir el tipo de
valor devuelto. Puede utilizar el descriptor de acceso de columna preexistente en DataRow (por ejemplo,
o["OrderDate"] ), pero hacerlo le exigiría convertir el objeto de valor devuelto al tipo apropiado. Si la columna es un
tipo de valor que acepta valores IsNull NULL, debe comprobar si el valor es null mediante el método. Para obtener
más información, vea Métodos genéricos Field y SetField.
Observe que el tipo de datos especificado en el parámetro T genérico de los métodos Field y SetField deben
coincidir con el tipo del valor subyacente; en caso contrario, se producirá una InvalidCastException. El nombre de
columna especificado debe también coincidir con el nombre de una columna en DataSet, en caso contrario, se
producirá una ArgumentException. En ambos casos, la excepción se produce en tiempo de ejecución de
enumeración de datos, cuando se ejecuta la consulta.
Vea también
Consultas entre tablas
Consultar objetos DataSet con tipo
Métodos genéricos Field y SetField
Consultas entre tablas (LINQ to DataSet)
08/01/2020 • 4 minutes to read • Edit Online
Además de consultar una sola tabla, también puede realizar consultas entre tablas en LINQ to DataSet. Esto se
realiza mediante una combinación. Una combinación es la asociación de objetos en un origen de datos con objetos
que comparten un atributo común en otro origen de datos, como un identificador de contacto o de producto. En la
programación orientada a objetos, las relaciones entre dichos objetos son relativamente fáciles de navegar debido
a que cada uno de ellos tiene un miembro que hace referencia a otro. Sin embargo, en tablas de bases de datos
externas, navegar por relaciones no es tan sencillo. Las tablas de bases de datos no contienen relaciones
integradas. En estos casos, la operación de combinación se puede utilizar para hacer coincidir elementos de cada
origen. Por ejemplo, con dos tablas que contienen información de producto y de ventas, se puede utilizar una
operación de combinación para hacer coincidir información de ventas y producto del mismo pedido de ventas.
El marco Language-Integrated Query (LINQ) proporciona dos operadores de combinación, Join y GroupJoin. Estos
operadores realizan combinaciones de igualdad: es decir, combinaciones que coinciden con dos orígenes de datos
solo cuando sus claves son iguales. (Por el contrario, Transact-SQL admite operadores de combinación distintos de
equals , como el operador less than ).
En cuanto a las bases de datos relacionales, Join implementa una combinación interna. Una combinación interna
es un tipo de combinación en la que solamente se devuelven los objetos que tienen una correspondencia en el
conjunto de datos opuesto.
Los operadores GroupJoin no tienen ningún equivalente directo en términos de bases de datos relacionales;
implementan un superconjunto de combinaciones internas y combinaciones externas izquierdas. Una combinación
externa izquierda es una combinación que devuelve cada elemento de la primera colección (izquierda), aunque
éste no tenga elementos correlacionados en la segunda colección.
Para obtener más información acerca de las combinaciones, vea operaciones de combinación.
Ejemplo
El ejemplo siguiente realiza una combinación tradicional de las tablas SalesOrderHeader y SalesOrderDetail de la
base de datos de ejemplo AdventureWorks para obtener pedidos en línea del mes de agosto.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from order in orders.AsEnumerable()
join detail in details.AsEnumerable()
on order.Field<int>("SalesOrderID") equals
detail.Field<int>("SalesOrderID")
where order.Field<bool>("OnlineOrderFlag") == true
&& order.Field<DateTime>("OrderDate").Month == 8
select new
{
SalesOrderID =
order.Field<int>("SalesOrderID"),
SalesOrderDetailID =
detail.Field<int>("SalesOrderDetailID"),
OrderDate =
order.Field<DateTime>("OrderDate"),
ProductID =
detail.Field<int>("ProductID")
};
Dim query = _
From order In orders.AsEnumerable() _
Join detail In details.AsEnumerable() _
On order.Field(Of Integer)("SalesOrderID") Equals _
detail.Field(Of Integer)("SalesOrderID") _
Where order.Field(Of Boolean)("OnlineOrderFlag") = True And _
order.Field(Of DateTime)("OrderDate").Month = 8 _
Select New With _
{ _
.SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
.SalesOrderDetailID = detail.Field(Of Integer)("SalesOrderDetailID"), _
.OrderDate = order.Field(Of DateTime)("OrderDate"), _
.ProductID = detail.Field(Of Integer)("ProductID") _
}
Vea también
Consulta de conjuntos de datos
Consultas de tabla única
Consultar objetos DataSet con tipo
Operaciones de combinación
Ejemplos de LINQ to DataSet
Consultar conjuntos de DataSet con tipo
23/10/2019 • 2 minutes to read • Edit Online
Si el esquema de se DataSet conoce en tiempo de diseño de la aplicación, se recomienda usar un DataSet tipo
cuando se use LINQ to DataSet. Un con tipo DataSet es una clase que se deriva DataSetde. Como tal, hereda todos
los métodos, eventos y propiedades de un DataSet. Además, un con tipo DataSet proporciona métodos, eventos y
propiedades fuertemente tipados. Esto significa que se puede tener acceso a tablas y columnas por su nombre, en
lugar de utilizar métodos de una colección. Esto hace que las consultas sean más sencillas y más legibles. Para
obtener más información, vea conjuntos de datos con tipo.
LINQ to DataSet también admite la consulta en un tipo DataSet. Con un tipo DataSet, no es necesario utilizar el
método o SetField método genérico Field para tener acceso a los datos de la columna. Los nombres de propiedad
están disponibles en tiempo de compilación porque la información de tipo DataSetse incluye en. LINQ to DataSet
proporciona acceso a los valores de columna como tipo correcto, de modo que los errores de coincidencia de tipos
se detectan cuando se compila el código en lugar de en tiempo de ejecución.
Antes de poder empezar a consultar un tipo DataSet, debe generar la clase mediante el diseñador de DataSet en
Visual Studio. Para obtener más información, vea crear y configurar conjuntosde datos.
Ejemplo
En el siguiente ejemplo se muestra una consulta sobre un DataSet con tipo:
Dim query = _
From o In orders _
Where o.OnlineOrderFlag = True _
Select New {SalesOrderID := o.SalesOrderID, _
OrderDate := o.OrderDate, _
SalesOrderNumber := o.SalesOrderNumber}
Language-Integrated Query (LINQ) define varios operadores de conjuntos para comparar los elementos de origen
y ver si son iguales. LINQ proporciona los siguientes operadores de conjuntos:
Distinct
Union
Intersect
Except
Estos operadores comparan elementos origen llamando a los métodos GetHashCode y Equals de cada colección
de elementos. En el caso de DataRow, estos operadores realizan una comparación de referencia, lo que en general
no constituye un comportamiento ideal para operaciones de conjunto en datos tabulares. Para las operaciones de
conjuntos, por lo general deseará determinar si los valores del elemento son iguales o no a las referencias del
elemento. Por lo tanto, se ha agregado la clase DataRowComparer a LINQ to DataSet. Esta clase se puede utilizar
para comparar valores de fila.
La clase DataRowComparer contiene una implementación de comparación del valor para DataRow, de modo que
esta clase se puede utilizar para operaciones de conjuntos como Distinct. No se puede crear una instancia
directamente de esta clase. En su lugar, debe utilizarse la propiedad Default para devolver una instancia de
DataRowComparer<TRow>. Entonces, se llama al método Equals y los dos objetos DataRow que se van a
comparar se pasan como parámetros de entrada. El método Equals devuelve true si los conjuntos ordenados de
valores de columna de ambos objetos DataRow son iguales; de lo contrario, devuelve false .
Ejemplo
Este ejemplo usa Intersect para devolver contactos que aparecen en ambas tablas.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
Dim query1 = _
From contact In contactTable.AsEnumerable() _
Where contact.Field(Of String)("Title") = "Ms." _
Select contact
Dim query2 = _
From contact In contactTable.AsEnumerable() _
Where contact.Field(Of String)("FirstName") = "Sandra" _
Select contact
Ejemplo
El ejemplo siguiente compara dos filas y obtiene sus códigos hash.
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)
Vea también
DataRowComparer
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Crear un objeto DataTable a partir de una consulta
(LINQ to DataSet)
21/03/2020 • 13 minutes to read • Edit Online
El enlace de datos es una utilización muy frecuente del objeto DataTable. El método CopyToDataTable toma los
resultados de una consulta y copia los datos en un objeto DataTable que puede utilizarse después para el enlace de
datos. Cuando las operaciones de datos se han realizado, el DataTable nuevo se vuelve a combinar en el DataTable
de origen.
El método CopyToDataTable utiliza el siguiente proceso para crear un DataTable a partir de una consulta:
1. El método CopyToDataTable clona un DataTable a partir de la tabla origen (un objeto DataTable que
implementa la interfaz IQueryable<T>). El IEnumerable origen se ha originado generalmente a partir de
una LINQ to DataSet expresión o consulta de método.
2. El esquema del DataTable clonado se compila a partir de las columnas del primer objeto DataRow
enumerado en la tabla origen; el nombre de la tabla clonada es el nombre de la tabla origen con la palabra
"query" anexada.
3. En cada fila de la tabla origen, el contenido de la fila se copia en un objetoDataRow nuevo, el cual, a
continuación, se inserta en la tabla clonada. Las propiedades RowState y RowError se mantienen en toda la
operación de copia. Si los objetos ArgumentException de origen pertenecen a tablas diferentes, se produce
unaDataRow.
4. Cuando todos los objetos DataTable de la tabla de entrada que se puede consultar se han copiado, se
devuelve el DataRow clonado. Si la secuencia origen no contiene objetos DataRow, el método devuelve un
DataTable vacío.
Llamar CopyToDataTable al método hace que se ejecute la consulta enlazada a la tabla de origen.
Cuando el método CopyToDataTable encuentra una referencia NULL o un tipo de valor que admite valores NULL
en una fila de la tabla origen, reemplaza el valor con Value. De este modo, los valores NULL se controlan
correctamente en el DataTable devuelto.
Nota: el método CopyToDataTable acepta como entrada una consulta que pueda devolver filas de varios objetos
DataTable o DataSet. El método CopyToDataTable copiará los datos pero no las propiedades desde los objetos
DataTable o DataSet de origen en el elemento DataTable que se va a devolver. Necesitará establecer explícitamente
las propiedades de los elementos DataTable devueltos, como Locale y TableName.
En el ejemplo siguiente se consultan en la tabla SalesOrderHeader los pedidos posteriores al 8 de agosto de 2001
y se utiliza el método CopyToDataTable para crear un DataTable a partir de esa consulta. A continuación, se enlaza
DataTable a un BindingSource, que actúa como proxy para un objeto DataGridView.
// Bind the System.Windows.Forms.DataGridView object
// to the System.Windows.Forms.BindingSource object.
dataGridView.DataSource = bindingSource;
End Class
Public Class Book
Inherits Item
Private _Author As String
Public Property Author() As String
Get
Return _Author
End Get
Set(ByVal value As String)
_Author = value
End Set
End Property
End Class
End Class
Ejemplo
En este ejemplo se realiza una combinación en las tablas SalesOrderHeader y SalesOrderDetail para obtener
pedidos en línea del mes de agosto y se crea una tabla a partir de la consulta.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from order in orders.AsEnumerable()
join detail in details.AsEnumerable()
on order.Field<int>("SalesOrderID") equals
detail.Field<int>("SalesOrderID")
where order.Field<bool>("OnlineOrderFlag") == true
&& order.Field<DateTime>("OrderDate").Month == 8
select new
{
SalesOrderID =
order.Field<int>("SalesOrderID"),
SalesOrderDetailID =
detail.Field<int>("SalesOrderDetailID"),
OrderDate =
order.Field<DateTime>("OrderDate"),
ProductID =
detail.Field<int>("ProductID")
};
Dim query = _
From order In orders.AsEnumerable() _
Join detail In details.AsEnumerable() _
On order.Field(Of Integer)("SalesOrderID") Equals _
detail.Field(Of Integer)("SalesOrderID") _
Where order.Field(Of Boolean)("OnlineOrderFlag") = True And _
order.Field(Of DateTime)("OrderDate").Month = 8 _
Select New With _
{ _
.SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
.SalesOrderDetailID = detail.Field(Of Integer)("SalesOrderDetailID"), _
.OrderDate = order.Field(Of DateTime)("OrderDate"), _
.ProductID = detail.Field(Of Integer)("ProductID") _
}
Ejemplo
En el ejemplo siguiente se consulta una colección de elementos cuyo precio es superior a $ 9,99 y se crea una tabla
a partir de los resultados de la consulta.
// Create a sequence.
Item[] items = new Item[]
{ new Book{Id = 1, Price = 13.50, Genre = "Comedy", Author = "Gustavo Achong"},
new Book{Id = 2, Price = 8.50, Genre = "Drama", Author = "Jessie Zeng"},
new Movie{Id = 1, Price = 22.99, Genre = "Comedy", Director = "Marissa Barnes"},
new Movie{Id = 1, Price = 13.40, Genre = "Action", Director = "Emmanuel Fernandez"}};
Ejemplo
En el ejemplo siguiente se consulta una colección de elementos cuyo precio es superior a $ 9,99 y se proyectan los
resultados. La secuencia de tipos anónimos devuelta se carga en una tabla existente.
// Create a sequence.
Item[] items = new Item[]
{ new Book{Id = 1, Price = 13.50, Genre = "Comedy", Author = "Gustavo Achong"},
new Book{Id = 2, Price = 8.50, Genre = "Drama", Author = "Jessie Zeng"},
new Movie{Id = 1, Price = 22.99, Genre = "Comedy", Director = "Marissa Barnes"},
new Movie{Id = 1, Price = 13.40, Genre = "Action", Director = "Emmanuel Fernandez"}};
// Create a table with a schema that matches that of the query results.
DataTable table = new DataTable();
table.Columns.Add("Price", typeof(int));
table.Columns.Add("Genre", typeof(string));
query.CopyToDataTable(table, LoadOption.PreserveChanges);
' Create a table with a schema that matches that of the query results.
Dim table As DataTable = New DataTable()
table.Columns.Add("Price", GetType(Integer))
table.Columns.Add("Genre", GetType(String))
query.CopyToDataTable(table, LoadOption.PreserveChanges)
Ejemplo
En el ejemplo siguiente se consulta una colección de elementos cuyo precio es superior a $ 9,99 y se proyectan los
resultados. La secuencia de tipos anónimos devuelta se carga en una tabla existente. El esquema de la tabla se
amplía automáticamente porque los tipos Book y Movies se derivan del tipo Item .
// Create a sequence.
Item[] items = new Item[]
{ new Book{Id = 1, Price = 13.50, Genre = "Comedy", Author = "Gustavo Achong"},
new Book{Id = 2, Price = 8.50, Genre = "Drama", Author = "Jessie Zeng"},
new Movie{Id = 1, Price = 22.99, Genre = "Comedy", Director = "Marissa Barnes"},
new Movie{Id = 1, Price = 13.40, Genre = "Action", Director = "Emmanuel Fernandez"}};
query.CopyToDataTable(table, LoadOption.PreserveChanges);
Dim book1 As New Book()
book1.Id = 1
book1.Price = 13.5
book1.Genre = "Comedy"
book1.Author = "Gustavo Achong"
query.CopyToDataTable(table, LoadOption.PreserveChanges)
Ejemplo
En el ejemplo siguiente se consulta una colección de elementos cuyo precio es superior a $ 9,99 y se devuelve una
secuencia de Double, que se carga en una tabla nueva.
// Create a sequence.
Item[] items = new Item[]
{ new Book{Id = 1, Price = 13.50, Genre = "Comedy", Author = "Gustavo Achong"},
new Book{Id = 2, Price = 8.50, Genre = "Drama", Author = "Jessie Zeng"},
new Movie{Id = 1, Price = 22.99, Genre = "Comedy", Director = "Marissa Barnes"},
new Movie{Id = 1, Price = 13.40, Genre = "Action", Director = "Emmanuel Fernandez"}};
Consulte también
Guía de programación
Métodos genéricos Field y SetField
Ejemplos de LINQ to DataSet
Cómo: Implementar CopyToDataTable<T> donde el
tipo genérico T no es un DataRow
27/03/2020 • 10 minutes to read • Edit Online
El objeto DataTable se suele utilizar para el enlace de datos. El método CopyToDataTable toma los resultados de
una consulta y copia los datos en un objeto DataTable que puede utilizarse después para el enlace de datos. Sin
embargo, los métodos CopyToDataTable solo funcionan en un origen IEnumerable<T> en el que el parámetro
genérico T es de tipo DataRow. Aunque esto es útil, no permite la creación de tablas a partir de una secuencia de
tipos escalares, a partir de consultas que proyectan tipos anónimos, o a partir de consultas que realizan
combinaciones de tablas.
En este tema se describe cómo se implementan dos métodos de extensión CopyToDataTable<T> personalizados
que aceptan un parámetro genérico T de un tipo distinto de DataRow. La lógica para crear un objeto DataTable
desde un origen IEnumerable<T> está contenida en la clase ObjectShredder<T> , que se incluye después en dos
métodos de extensión CopyToDataTable<T> sobrecargados. El método Shred de la clase ObjectShredder<T>
devuelve el objeto DataTable relleno y acepta tres parámetros de entrada: un origen IEnumerable<T>, un objeto
DataTable y una enumeración LoadOption. El esquema inicial del objeto DataTable devuelto está basado en el
esquema del tipo T . Si se proporciona una tabla existente como entrada, el esquema debe ser coherente con el
esquema del tipo T . Cada propiedad y campo públicos del tipo T se convierten a un objeto DataColumn en la
tabla devuelta. Si la secuencia de origen contiene un tipo derivado de T , el esquema de la tabla devuelta se
expande para las propiedades o campos públicos adicionales.
Para obtener ejemplos de uso de los métodos CopyToDataTable<T> personalizados, vea Crear un objeto DataTable a
partir de una consulta.
Para implementar los métodos CopyToDataTable<T> personalizados en la aplicación
1. Implemente la clase ObjectShredder<T> para crear un objeto DataTable desde un origen IEnumerable<T>:
// ObjectShredder constructor.
public ObjectShredder()
{
_type = typeof(T);
_fi = _type.GetFields();
_pi = _type.GetProperties();
_ordinalMap = new Dictionary<string, int>();
}
/// <summary>
/// Loads a DataTable from a sequence of objects.
/// </summary>
/// <param name="source">The sequence of objects to load into the DataTable.</param>
/// <param name="table">The input table. The schema of the table must match that
/// the type T. If the table is null, a new table is created with a schema
/// created from the public properties and fields of the type T.</param>
/// <param name="options">Specifies how values from the source sequence will be applied to
/// existing rows in the table.</param>
/// <returns>A DataTable created from the source sequence.</returns>
public DataTable Shred(IEnumerable<T> source, DataTable table, LoadOption? options)
public DataTable Shred(IEnumerable<T> source, DataTable table, LoadOption? options)
{
// Load the table from the scalar sequence if T is a primitive type.
if (typeof(T).IsPrimitive)
{
return ShredPrimitive(source, table, options);
}
// Initialize the ordinal map and extend the table schema based on type T.
table = ExtendTable(table, typeof(T));
// Enumerate the source sequence and load the object values into rows.
table.BeginLoadData();
using (IEnumerator<T> e = source.GetEnumerator())
{
while (e.MoveNext())
{
if (options != null)
{
table.LoadDataRow(ShredObject(table, e.Current), (LoadOption)options);
}
else
{
table.LoadDataRow(ShredObject(table, e.Current), true);
}
}
}
table.EndLoadData();
if (!table.Columns.Contains("Value"))
{
table.Columns.Add("Value", typeof(T));
}
// Enumerate the source sequence and load the scalar values into rows.
table.BeginLoadData();
using (IEnumerator<T> e = source.GetEnumerator())
{
Object[] values = new object[table.Columns.Count];
while (e.MoveNext())
{
values[table.Columns["Value"].Ordinal] = e.Current;
if (options != null)
{
table.LoadDataRow(values, (LoadOption)options);
}
else
{
table.LoadDataRow(values, true);
}
}
}
table.EndLoadData();
FieldInfo[] fi = _fi;
PropertyInfo[] pi = _pi;
if (instance.GetType() != typeof(T))
{
// If the instance is derived from T, extend the table schema
// and get the properties and fields.
ExtendTable(table, instance.GetType());
fi = instance.GetType().GetFields();
pi = instance.GetType().GetProperties();
}
' Constructor
Public Sub New()
Me._type = GetType(T)
Me._fi = Me._type.GetFields
Me._pi = Me._type.GetProperties
Me._ordinalMap = New Dictionary(Of String, Integer)
End Sub
' Add the property and field values of the instance to an array.
Dim values As Object() = New Object(table.Columns.Count - 1) {}
Dim f As FieldInfo
For Each f In fi
values(Me._ordinalMap.Item(f.Name)) = f.GetValue(instance)
Next
Dim p As PropertyInfo
For Each p In pi
values(Me._ordinalMap.Item(p.Name)) = p.GetValue(instance, Nothing)
Next
Public Function Shred(ByVal source As IEnumerable(Of T), ByVal table As DataTable, ByVal options As
LoadOption?) As DataTable
' Load the table from the scalar sequence if T is a primitive type.
If GetType(T).IsPrimitive Then
Return Me.ShredPrimitive(source, table, options)
End If
' Initialize the ordinal map and extend the table schema based on type T.
table = Me.ExtendTable(table, GetType(T))
' Enumerate the source sequence and load the object values into rows.
table.BeginLoadData()
Using e As IEnumerator(Of T) = source.GetEnumerator
Do While e.MoveNext
If options.HasValue Then
table.LoadDataRow(Me.ShredObject(table, e.Current), options.Value)
Else
table.LoadDataRow(Me.ShredObject(table, e.Current), True)
End If
Loop
End Using
table.EndLoadData()
Public Function ShredPrimitive(ByVal source As IEnumerable(Of T), ByVal table As DataTable, ByVal
options As LoadOption?) As DataTable
' Create a new table if the input table is null.
If (table Is Nothing) Then
table = New DataTable(GetType(T).Name)
End If
If Not table.Columns.Contains("Value") Then
table.Columns.Add("Value", GetType(T))
End If
' Enumerate the source sequence and load the scalar values into rows.
table.BeginLoadData()
Using e As IEnumerator(Of T) = source.GetEnumerator
Dim values As Object() = New Object(table.Columns.Count - 1) {}
Do While e.MoveNext
values(table.Columns.Item("Value").Ordinal) = e.Current
If options.HasValue Then
table.LoadDataRow(values, options.Value)
Else
table.LoadDataRow(values, True)
End If
Loop
End Using
table.EndLoadData()
Next
End Class
En el ejemplo anterior se supone DataColumn que las propiedades de la no son tipos de valor que aceptan
valores NULL. Para controlar las propiedades con tipos de valor que aceptan valores NULL, utilice el código
siguiente:
<Extension()> _
Public Function CopyToDataTable(Of T)(ByVal source As IEnumerable(Of T), ByVal table As DataTable,
ByVal options As LoadOption?) As DataTable
Return New ObjectShredder(Of T)().Shred(source, table, options)
End Function
End Module
class Program
{
static void Main(string[] args)
{
// Your application code using CopyToDataTable<T>.
}
}
public static class CustomLINQtoDataSetMethods
{
…
}
public class ObjectShredder<T>
{
…
}
Vea también
Creación de un objeto DataTable a partir de una consulta
Guía de programación
Métodos genéricos Field y SetField (LINQ to
DataSet)
27/03/2020 • 4 minutes to read • Edit Online
LINQ to DataSetLINQ to DataRow DataSet proporciona métodos de extensión a la clase para tener acceso a los
valores de columna: el Field método y el SetField método. Estos métodos facilitan el acceso a los valores de
columna a los desarrolladores, sobre todo en lo relativo a valores NULL. El DataSet DBNull.Value uso para
representar valores null, Nullable Nullable<T> mientras que LINQ usa los tipos y. El uso del descriptor DataRow
de acceso de columna preexistente en requiere que convierta el objeto devuelto al tipo adecuado. Si un campo
DataRow determinado en un puede ser null, debe comprobar DBNull.Value explícitamente si hay un valor
InvalidCastExceptionnulo porque devolverlo e horizontalmente convertirlo a otro tipo produce un archivo . En el
ejemplo siguiente, si el DataRow.IsNull método no se usó para comprobar si hay DBNull.Value un valor nulo,
Stringse produciría una excepción si el indizador devolvió e intentó convertirlo en un archivo .
var query =
from product in products.AsEnumerable()
where !product.IsNull("Color") &&
(string)product["Color"] == "Red"
select new
{
Name = product["Name"],
ProductNumber = product["ProductNumber"],
ListPrice = product["ListPrice"]
};
Dim query = _
From product In products.AsEnumerable() _
Where product!Color IsNot DBNull.Value AndAlso product!Color = "Red" _
Select New With _
{ _
.Name = product!Name, _
.ProductNumber = product!ProductNumber, _
.ListPrice = product!ListPrice _
}
El método Field proporciona acceso a los valores de columna de DataRow y SetField establece los valores de
columna en DataRow. Tanto Field el SetField método como el método controlan los tipos de valor que aceptan
valores NULL, por lo que no es necesario comprobar explícitamente los valores NU como en el ejemplo anterior.
Además, ambos son métodos genéricos, lo que significa que no es necesario convertir el tipo de valor devuelto.
El siguiente ejemplo utiliza el método Field.
var query =
from product in products.AsEnumerable()
where product.Field<string>("Color") == "Red"
select new
{
Name = product.Field<string>("Name"),
ProductNumber = product.Field<string>("ProductNumber"),
ListPrice = product.Field<Decimal>("ListPrice")
};
Dim query = _
From product In products.AsEnumerable() _
Where product.Field(Of String)("Color") = "Red" _
Select New With _
{ _
.Name = product.Field(Of String)("Name"), _
.ProductNumber = product.Field(Of String)("ProductNumber"), _
.ListPrice = product.Field(Of Decimal)("ListPrice") _
}
Observe que el tipo de datos especificado en el parámetro T genérico de los métodos Field y SetField deben
coincidir con el tipo del valor subyacente. De lo contrario, se producirá una excepción InvalidCastException. El
nombre de columna especificado debe también coincidir con el nombre de una columna en DataSet; en caso
contrario, se producirá una ArgumentException. En ambos casos, la excepción se produce en tiempo de ejecución
durante la enumeración de datos cuando se ejecuta la consulta.
El método SetField en sí no realiza ninguna conversión de tipos. Sin embargo, esto no significa que no se realizará
una conversión de tipos. El SetField método expone el comportamiento DataRow ADO.NET de la clase. El objeto
podría realizar DataRow una conversión de tipos y DataRow el valor convertido se guardaría en el objeto.
Vea también
DataRowExtensions
Enlace de datos y LINQ to DataSet
08/01/2020 • 3 minutes to read • Edit Online
El enlace de datos es el proceso que establece una conexión entre la interfaz de usuario de la aplicación y la lógica
de negocios. Si el enlace está configurado correctamente y los datos proporcionan la notificaciones adecuadas, al
cambiar los valores de los datos, los elementos enlazados a los mismos reflejarán de manera automática dichos
cambios. DataSet es una representación de datos residente en memoria que proporciona un modelo de
programación relacional coherente independientemente del origen de datos que contiene. DataView de ADO.NET
2.0 permite ordenar y filtrar los datos almacenados en DataTable. Esta funcionalidad se utiliza con frecuencia en
aplicaciones de enlace de datos. Mediante DataView puede exponer los datos de una tabla con distintos criterios
de ordenación y filtrar los datos por el estado de fila o basándose en una expresión de filtro. Para obtener más
información sobre el objeto DataView, vea objetos de datos.
LINQ to DataSet permite a los desarrolladores crear consultas complejas y eficaces en un DataSet mediante el uso
de Language-Integrated Query (LINQ). Sin embargo, una consulta de LINQ to DataSet devuelve una enumeración
de objetos DataRow, que no se usa fácilmente en un escenario de enlace. Para facilitar el enlace, puede crear una
DataView a partir de una consulta de LINQ to DataSet. Este DataView utiliza el filtrado y la ordenación
especificados en la consulta, pero es más adecuado para el enlace de datos. LINQ to DataSet extiende la
funcionalidad del DataView proporcionando filtrado y ordenación basados en expresiones de LINQ, lo que permite
operaciones de filtrado y ordenación mucho más complejas y eficaces que el filtrado y la ordenación basados en
cadenas.
Observe que DataView representa la propia consulta y no es una vista encima de la consulta. DataView se enlaza a
un control de la interfaz de usuario, como DataGrid o DataGridView, proporcionando un modelo de enlace de
datos simple. DataView se puede crear también a partir de DataTable, proporcionando una vista predeterminada
de esa tabla.
Esta sección
Creación de un objeto DataView
Proporciona información sobre creación de DataView.
Filtrado con DataView
Describe cómo filtrar con DataView.
Ordenación con DataView
Describe cómo ordenar con DataView.
Consulta de la colección de DataRowView en un objeto DataView
Proporciona información sobre cómo consultar la colección DataRowView expuesta por DataView.
Rendimiento de DataView
Proporciona información sobre DataView y rendimiento.
Enlace de un objeto DataView a un control DataGridView de Windows Forms
Describe cómo enlazar un objeto DataView a DataGridView.
Vea también
Guía de programación
Crear un objeto DataView (LINQ to DataSet)
23/10/2019 • 7 minutes to read • Edit Online
Hay dos maneras de crear un DataView en el contexto de LINQ to DataSet. Puede crear a DataView partir de una
consulta de LINQ to DataSet sobre DataTableun, o puede crearlo a partir de un tipo DataTableo sin tipo. En ambos
casos, se crea DataView mediante uno de los AsDataView métodos de extensión; DataView no se construye
directamente en el contexto de LINQ to DataSet.
Cuando se ha creado DataView, puede enlazarlo con un control de la interfaz de usuario en una aplicación de
Windows Forms o en una aplicación ASP.NET, o cambiar la configuración de filtro y ordenación.
DataView construye un índice, que mejora considerablemente el rendimiento de las operaciones que pueden
utilizarlo, como filtro y ordenación. El índice de DataView se compila cuando se crea DataView y cuando se
modifica cualquier información de filtro u ordenación. La creación de DataView y el posterior establecimiento de
información de filtro y ordenación hace que el índice se compile al menos dos veces: una cuando se crea DataView
y la otra cuando se modifica cualquiera de las propiedades de ordenación y filtrado.
Para obtener más información sobre el filtrado y la DataViewordenación con, vea filtrar con DataView y ordenar
con DataView.
NOTE
En la mayor parte de los casos, las expresiones utilizadas en el filtrado y la ordenación no deben tener efectos secundarios y
deben ser deterministas. Además, las expresiones no deben tener ninguna lógica que dependa de un número de conjunto de
ejecuciones, ya que las operaciones de filtrado y ordenación se pueden ejecutar un número ilimitado de veces.
No se admite la creación de DataView a partir de una consulta que devuelve tipos anónimos o consultas que
realizan operaciones de combinación.
Sólo se admiten los siguientes operadores de consulta en una consulta utilizada para crear DataView:
Cast
OrderBy
OrderByDescending
Select
ThenBy
ThenByDescending
Where
Tenga en cuenta que DataView cuando se crea un a partir de Select una consulta de LINQ to DataSet, el método
debe ser el último método llamado en la consulta. Esto se muestra en el ejemplo siguiente, que crea un DataView
de pedidos en línea ordenados por el total a pagar:
DataTable orders = dataSet.Tables["SalesOrderHeader"];
EnumerableRowCollection<DataRow> query =
from order in orders.AsEnumerable()
where order.Field<bool>("OnlineOrderFlag") == true
orderby order.Field<decimal>("TotalDue")
select order;
bindingSource1.DataSource = view;
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of Boolean)("OnlineOrderFlag") = True _
Order By order.Field(Of Decimal)("TotalDue") _
Select order
También puede utilizar las propiedades y RowFilter Sort basadas en cadenas para filtrar y ordenar una DataView
después de que se haya creado a partir de una consulta. Observe que con esto se borrará la información de
ordenación y filtro heredada de la consulta. En el ejemplo siguiente se DataView crea un a partir de una LINQ to
DataSet consulta que filtra por los apellidos que empiezan por ' a '. La propiedad basada en cadena Sort se
establece para ordenar por apellidos en orden ascendente y después por nombres en orden descendente:
bindingSource1.DataSource = view;
Dim query = _
From contact In contacts.AsEnumerable() _
Where contact.Field(Of String)("LastName").StartsWith("S") _
Select contact
dataGridView1.AutoResizeColumns();
El filtro y la ordenación pueden establecerse en DataView después de que se haya creado a partir de DataTable. El
ejemplo siguiente crea DataView a partir de la tabla Contact y establece la propiedad Sort para ordenar por
apellidos en orden ascendente y luego por nombres en orden descendente:
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
No obstante, se produce una pérdida de rendimiento cuando se establece la propiedad RowFilter o Sort después
de haberse creado DataView a partir de una consulta, debido a que DataView construye un índice para admitir
operaciones de filtro y ordenación. El establecimiento de la propiedad RowFilter o Sort hace que se recompile el
índice de los datos, lo que agrega sobrecarga a la aplicación y reduce el rendimiento. Siempre que sea posible, se
recomienda especificar la información sobre filtro y ordenación cuando se cree por primera vez DataView y evitar
modificaciones posteriores.
Vea también
Enlace de datos y LINQ to DataSet
Filtrado con DataView
Ordenación con DataView
Filtrar con DataView (LINQ to DataSet)
08/01/2020 • 14 minutes to read • Edit Online
La capacidad de filtrar datos utilizando criterios específicos y después presentarlos a un cliente mediante un
control de IU es un aspecto importante del enlace de datos. DataView proporciona varias maneras de filtrar datos
y devolver subconjuntos de filas de datos que reúnan determinados criterios. Además de las funcionalidades de
filtrado basadas en cadenas, DataView también proporciona la capacidad de usar expresiones LINQ para los
criterios de filtrado. Las expresiones LINQ permiten operaciones de filtrado mucho más complejas y eficaces que
el filtrado basado en cadenas.
Existen dos maneras de filtrar datos utilizando DataView:
Cree una DataView a partir de una consulta de LINQ to DataSet con una cláusula WHERE.
Utilizar las capacidades de filtro basado en cadena de DataView existentes.
NOTE
En la mayor parte de los casos, las expresiones utilizadas en el filtro no deben tener efectos secundarios y deben ser
deterministas. Además, las expresiones no deben tener ninguna lógica que dependa de un número de conjunto de
ejecuciones, porque las operaciones de filtrado se pueden ejecutar un número ilimitado de veces.
Ejemplo
El siguiente ejemplo consulta en la tabla SalesOrderDetail los pedidos con una cantidad superior a 2 e inferior a 6;
crea un DataView desde una consulta y enlaza DataView a un BindingSource:
bindingSource1.DataSource = view;
Dim orders As DataTable = dataSet.Tables("SalesOrderDetail")
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of Int16)("OrderQty") > 2 And _
order.Field(Of Int16)("OrderQty") < 6 _
Select order
Ejemplo
El siguiente ejemplo crea un DataView desde una consulta de pedidos efectuados con posterioridad al 6 de junio
de 2001:
bindingSource1.DataSource = view;
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of DateTime)("OrderDate") > New DateTime(2002, 6, 1) _
Select order
Ejemplo
El filtro se puede combinar también con la ordenación. El siguiente ejemplo crea un DataView desde una consulta
de contactos cuyos apellidos empiezan por la letra "S", y los ordena primero por el apellido y después por el
nombre:
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
Dim contacts As DataTable = dataSet.Tables("Contact")
Dim query = _
From contact In contacts.AsEnumerable() _
Where contact.Field(Of String)("LastName").StartsWith("S") _
Order By contact.Field(Of String)("LastName"), contact.Field(Of String)("FirstName") _
Select contact
Ejemplo
El siguiente ejemplo utiliza el algoritmo SoundEx para encontrar contactos cuyo apellido es similar a "Zhu". El
algoritmo SoundEx se implementa en el método SoundEx.
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
Dim query = _
From contact In contacts.AsEnumerable() _
Where SoundEx(contact.Field(Of String)("LastName")) = soundExCode _
Select contact
SoundEx es un algoritmo fonético utilizado para indizar nombres según el sonido, tal como se pronuncian en
inglés, que fue desarrollado originalmente por la Oficina del Censo de Estados Unidos. El método SoundEx
devuelve un código de cuatro caracteres para un nombre que consiste en una letra inglesa seguida de tres
números. La letra es la primera letra del nombre y los números codifican el resto de las consonantes del mismo.
Los nombres que suenan parecidos comparten el mismo código SoundEx. A continuación se muestra la
implementación del SoundEx utilizado en el método SoundEx del ejemplo anterior:
// Value to return.
string value = "";
// Loop through all the characters and convert them to the proper character code.
for (int i = 1; i < size; i++)
{
switch (chars[i])
{
case 'A':
case 'E':
case 'I':
case 'O':
case 'U':
case 'H':
case 'W':
case 'Y':
currCode = 0;
break;
case 'B':
case 'F':
case 'P':
case 'V':
currCode = 1;
break;
case 'C':
case 'G':
case 'J':
case 'K':
case 'Q':
case 'S':
case 'X':
case 'Z':
currCode = 2;
break;
case 'D':
case 'T':
currCode = 3;
break;
case 'L':
currCode = 4;
break;
case 'M':
case 'N':
currCode = 5;
break;
case 'R':
currCode = 6;
break;
}
// If the buffer size meets the length limit, exit the loop.
if (buffer.Length == length)
break;
}
// Pad the buffer, if required.
size = buffer.Length;
if (size < length)
buffer.Append('0', (length - size));
Case "L"
currCode = 4
Case "R"
currCode = 6
currCode = 6
End Select
' Check to see if the current code is the same as the last one
If (currCode <> prevCode) Then
' Check to see if the current code is 0 (a vowel); do not process vowels
If (currCode <> 0) Then
buffer.Append(currCode)
End If
End If
' Set the new previous character code
prevCode = currCode
' If the buffer size meets the length limit, then exit the loop
If (buffer.Length = length) Then
Exit For
End If
Next
' Pad the buffer, if required
size = buffer.Length
If (size < length) Then
buffer.Append("0", (length - size))
End If
' Set the value to return
value = buffer.ToString()
End If
' Return the value
Return value
End Function
view.RowFilter = "LastName='Zhu'";
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
Una vez creada una DataView a partir de una consulta de DataTable o LINQ to DataSet, puede usar la propiedad
RowFilter para especificar subconjuntos de filas basándose en sus valores de columna. Los filtros basados en
cadena y los basados en expresión se excluyen mutuamente. Al establecer la propiedad RowFilter se borrará la
expresión de filtro que se deduce de la consulta LINQ to DataSet y no se puede restablecer la expresión de filtro.
DataTable contacts = dataSet.Tables["Contact"];
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
view.RowFilter = "LastName='Zhu'";
Dim query = _
From contact In contacts.AsEnumerable() _
Where contact.Field(Of String)("LastName") = "Hernandez" _
Select contact
dataGridView1.AutoResizeColumns()
view.RowFilter = "LastName='Zhu'"
Si desea devolver los resultados de una consulta determinada en los datos, en lugar de proporcionar una vista
dinámica de un subconjunto de los datos, para conseguir el máximo rendimiento puede utilizar los métodos Find
o FindRows de la DataView, en lugar de establecer la propiedad RowFilter. La propiedad RowFilter es más idónea
en una aplicación enlazada a datos donde un control enlazado muestra resultados filtrados. El establecimiento de
la propiedad RowFilter hace que se recompile el índice de los datos, lo que agrega sobrecarga a la aplicación y
reduce el rendimiento. Los métodos Find y FindRows utilizan el índice actual, sin necesidad de recompilarlo. Si va
a llamar a Find o a FindRows una única vez, entonces debería utilizar el DataView existente. Si va a llamar a Find o
a FindRows varias veces, debería crear un nuevo DataView para recompilar el índice en la columna en la que
desea buscar y, a continuación, llamar a los métodos Find o FindRows. Para obtener más información sobre los
métodos Find y FindRows, vea Buscar filas y rendimiento de DataView.
Borrar el filtro
Después de haber configurado el filtro de DataView, éste se puede borrar mediante la propiedad RowFilter. El
filtro de DataView se pude borrar de dos maneras:
Establezca la propiedad RowFilter en null .
Establecer la propiedad RowFilter en una cadena vacía.
Ejemplo
El siguiente ejemplo crea un DataView desde una consulta y, a continuación, borra el filtro estableciendo la
propiedad RowFilter en null :
DataTable orders = dataSet.Tables["SalesOrderHeader"];
bindingSource1.DataSource = view;
view.RowFilter = null;
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of DateTime)("OrderDate") > New DateTime(2002, 11, 20) _
And order.Field(Of Decimal)("TotalDue") < New Decimal(60.0) _
Select order
Ejemplo
El siguiente ejemplo crea un DataView desde una tabla, establece la propiedad RowFilter y, a continuación, borra
el filtro estableciendo la propiedad RowFilter en una cadena vacía:
view.RowFilter = "LastName='Zhu'";
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
Vea también
Enlace de datos y LINQ to DataSet
Ordenación con DataView
Ordenar con DataView (LINQ to DataSet)
08/01/2020 • 8 minutes to read • Edit Online
La ordenación basada en expresión es más eficaz y compleja que la simple ordenación basada en cadena.
Observe que la ordenación basada en cadena y expresión se excluyen mutuamente. Cuando el Sort basado en
cadena se establece después de haber creado DataView desde una consulta, el filtro basado en expresión inferido
a partir de la consulta se borra y no se puede volver a restablecer.
El índice de DataView se compila cuando se crea DataView y cuando se modifica cualquier información de filtro u
ordenación. Para obtener el mejor rendimiento, proporcione criterios de ordenación en la consulta LINQ to
DataSet en la que se crea el DataView y sin modificar la información de ordenación, más adelante. Para obtener
más información, vea rendimiento de DataView.
NOTE
En la mayor parte de los casos, las expresiones utilizadas en la ordenación no deben tener efectos secundarios y deben ser
deterministas. Además, las expresiones no deben tener ninguna lógica que dependa de un número de conjunto de
ejecuciones, porque las operaciones de ordenación se pueden ejecutar un número ilimitado de veces.
Ejemplo
El siguiente ejemplo consulta en la tabla SalesOrderHeader y ordena las filas devueltas por fecha de pedido; crea
un DataView desde una consulta y enlaza DataView a un BindingSource:
bindingSource1.DataSource = view;
Dim orders As DataTable = dataSet.Tables("SalesOrderHeader")
Dim query = _
From order In orders.AsEnumerable() _
Order By order.Field(Of DateTime)("OrderDate") _
Select order
Ejemplo
El siguiente ejemplo consulta en la tabla SalesOrderHeader y ordena la fila devuelta por el importe total a pagar;
crea un DataView desde una consulta y enlaza DataView a un BindingSource:
EnumerableRowCollection<DataRow> query =
from order in orders.AsEnumerable()
orderby order.Field<decimal>("TotalDue")
select order;
bindingSource1.DataSource = view;
Dim query = _
From order In orders.AsEnumerable() _
Order By order.Field(Of Decimal)("TotalDue") _
Select order
Ejemplo
El siguiente ejemplo consulta en la tabla SalesOrderDetail y ordena las filas devueltas por cantidad de pedido y, a
continuación, por id. del pedido de ventas; crea un DataView desde una consulta y enlaza DataView a un
BindingSource:
bindingSource1.DataSource = view;
Dim orders As DataTable = dataSet.Tables("SalesOrderDetail")
Dim query = _
From order In orders.AsEnumerable() _
Order By order.Field(Of Int16)("OrderQty"), order.Field(Of Integer)("SalesOrderID") _
Select order
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
Ejemplo
En el siguiente ejemplo se consultan los apellidos que empiezan por la letra "S" en la tabla Contact. Se crea una
clase DataView a partir de dicha consulta y se enlaza a un objeto BindingSource.
DataTable contacts = dataSet.Tables["Contact"];
bindingSource1.DataSource = view;
Dim query = _
From contact In contacts.AsEnumerable() _
Where contact.Field(Of String)("LastName").StartsWith("S") _
Select contact
Borrar la ordenación
Se puede borrar la información de ordenación de DataView después de haberla establecido mediante la
propiedad Sort. Hay dos formas de borrar información de ordenación en DataView:
Establezca la propiedad Sort en null .
Establecer la propiedad Sort en una cadena vacía.
Ejemplo
El siguiente ejemplo crea un DataView desde una consulta y borra la ordenación mediante el establecimiento de
la propiedad Sort en una cadena vacía:
bindingSource1.DataSource = view;
view.Sort = "";
Dim query = _
From order In orders.AsEnumerable() _
Order By order.Field(Of Decimal)("TotalDue") _
Select order
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
bindingSource1.DataSource = view
dataGridView1.AutoResizeColumns()
Vea también
Enlace de datos y LINQ to DataSet
Filtrado con DataView
Ordenación de datos
Consultar la colección de DataRowView en un objeto
DataView
23/10/2019 • 4 minutes to read • Edit Online
El objeto DataView expone una colección enumerable de objetos DataRowView. DataRowView representa una vista
personalizada de un objeto DataRow y muestra una versión concreta de dicho objeto DataRow en un control. Solo
se puede mostrar una versión de un objeto DataRow mediante un control, como por ejemplo, DataGridView. Se
puede tener acceso al objeto DataRow que está expuesto por DataRowView mediante la propiedad Row de
DataRowView. Cuando se ven valores mediante el uso de DataRowView, la propiedad RowStateFilter determina
qué versión de fila del objeto DataRow subyacente está expuesta. Para obtener información sobre cómo obtener
acceso a diferentes versiones DataRowde fila mediante, vea Estados de fila y versiones de fila. Dado que la
colección DataRowView de objetos expuesta DataView por es Enumerable, puede utilizar LINQ to DataSet para
realizar consultas sobre él.
En el ejemplo siguiente se realiza una consulta en la tabla Product para los productos de color rojo y se crea una
tabla a partir de dicha consulta. Se crea un objeto DataView a partir de la tabla y se establece la propiedad
RowStateFilter para filtrar por filas modificadas o eliminadas. DataView se utiliza después como origen en una
consulta LINQ, y los objetos DataRowView que se han modificado y eliminado se enlazan a un control
DataGridView.
dataGridView2.DataSource = modifiedDeletedQuery.ToList();
Dim products As DataTable = dataSet.Tables("Product")
dataGridView2.DataSource = modifiedDeletedQuery.ToList()
En el ejemplo siguiente se crea una tabla de productos a partir de una vista que se enlaza a un control
DataGridView. Se realiza una consulta en DataView para los productos de color rojo y los resultados ordenados se
enlazan a un control DataGridView.
// Query the DataView for red colored products ordered by list price.
var productQuery = from DataRowView rowView in view
where rowView.Row.Field<string>("Color") == "Red"
orderby rowView.Row.Field<decimal>("ListPrice")
select new { Name = rowView.Row.Field<string>("Name"),
Color = rowView.Row.Field<string>("Color"),
Price = rowView.Row.Field<decimal>("ListPrice")};
' Query the DataView for red colored products ordered by list price.
Dim productQuery = From rowView As DataRowView In view _
Where rowView.Row.Field(Of String)("Color") = "Red" _
Order By rowView.Row.Field(Of Decimal)("ListPrice") _
Select New With {.Name = rowView.Row.Field(Of String)("Name"), _
.Color = rowView.Row.Field(Of String)("Color"), _
.Price = rowView.Row.Field(Of Decimal)("ListPrice")}
Vea también
Enlace de datos y LINQ to DataSet
Rendimiento de DataView
21/03/2020 • 5 minutes to read • Edit Online
En este tema se abordan las ventajas del uso de los métodos Find y FindRows de la clase DataView, y del
almacenamiento en memoria caché de DataView en una aplicación web.
Find y FindRows
DataView construye un índice. Un índice contiene claves generadas a partir de una o varias columnas de la tabla o
la vista. Dichas claves están almacenadas en una estructura que permite que DataView busque de forma rápida y
eficiente la fila o filas asociadas a los valores de cada clave. Las operaciones que usan el índice, como el filtrado y
la ordenación, ven aumentos significativos del rendimiento. El índice de DataView se compila cuando se crea
DataView y cuando se modifica cualquier información de filtro u ordenación. La creación de DataView y el
posterior establecimiento de información de filtro y ordenación hace que el índice se compile al menos dos veces:
una cuando se crea DataView y la otra cuando se modifica cualquiera de las propiedades de ordenación y filtrado.
Para obtener más información DataViewsobre cómo filtrar y ordenar con , vea Filtrado con DataView y
Ordenación con DataView.
Si desea devolver los resultados de una consulta determinada en los datos, en lugar de proporcionar una vista
dinámica de un subconjunto de los datos, para conseguir el máximo rendimiento puede utilizar los métodos Find
o FindRows de la DataView, en lugar de establecer la propiedad RowFilter. La propiedad RowFilter es más idónea
en una aplicación enlazada a datos donde un control enlazado muestra resultados filtrados. El establecimiento de
la propiedad RowFilter hace que se recompile el índice de los datos, lo que agrega sobrecarga a la aplicación y
reduce el rendimiento. Los métodos Find y FindRows utilizan el índice actual, sin necesidad de recompilarlo. Si va
a llamar a Find o a FindRows una única vez, entonces debería utilizar el DataView existente. Si va a llamar a Find o
a FindRows varias veces, debería crear un nuevo DataView para recompilar el índice en la columna en la que
desea buscar y, a continuación, llamar a los métodos Find o FindRows. Para obtener más Find FindRows
información acerca de los métodos, vea Buscar filas.
El ejemplo siguiente utiliza el método Find para buscar un contacto con el apellido "Zhu".
Dim query = _
From contact In contacts.AsEnumerable() _
Order By contact.Field(Of String)("LastName") _
Select contact
En el ejemplo siguiente se usa el método FindRows para buscar todos los productos de color rojo.
view.Sort = "Color";
Dim query = _
From product In products.AsEnumerable() _
Order By product.Field(Of Decimal)("ListPrice"), product.Field(Of String)("Color") _
Select product
ASP.NET
ASP.NET dispone de un mecanismo de almacenamiento en memoria caché de objetos cuya creación en memoria
requiere una gran cantidad de recursos del servidor. Si se almacenan estos tipos de recursos en la memoria caché
se puede mejorar de forma significativa el rendimiento de la aplicación. La clase Cache implementa el
almacenamiento en memoria caché, con instancias de la memoria caché privadas para cada aplicación. Dado que
la creación de un objeto DataView nuevo puede consumir muchos recursos, quizás desee utilizar esta
funcionalidad de almacenamiento en caché en aplicaciones web para que DataView no tenga que recompilarse
cada vez que se actualiza la página web.
En el ejemplo siguiente, DataView se almacena en caché para que los datos no tengan que volver a ordenarse
cuando la página se actualice.
If (Cache("ordersView") = Nothing) Then
FillDataSet(dataSet)
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of Boolean)("OnlineOrderFlag") = True _
Order By order.Field(Of Decimal)("TotalDue") _
Select order
Cache.Insert("ordersView", view)
End If
GridView1.DataSource = ordersView
GridView1.DataBind()
if (Cache["ordersView"] == null)
{
// Fill the DataSet.
DataSet dataSet = FillDataSet();
EnumerableRowCollection<DataRow> query =
from order in orders.AsEnumerable()
where order.Field<bool>("OnlineOrderFlag") == true
orderby order.Field<decimal>("TotalDue")
select order;
GridView1.DataSource = ordersView;
GridView1.DataBind();
Consulte también
Enlace de datos y LINQ to DataSet
Procedimiento para enlazar un objeto DataView a un
control DataGridView de formularios Windows Forms
23/10/2019 • 4 minutes to read • Edit Online
El control DataGridView proporciona una forma eficaz y flexible de mostrar datos en formato de tabla. El control
DataGridView admite el modelo de enlace de datos de Windows Forms estándar, por lo que se enlazará a DataView
y a otros orígenes de datos. Sin embargo, en la mayoría de las situaciones se enlazará a un componente
BindingSource que administrará los detalles de la interacción con el origen de datos.
Para obtener más información sobre DataGridView el control, vea información general sobre el control
DataGridView.
Para conectar un control DataGridView a DataView
1. Implemente un método que controle los detalles de recuperación de datos desde una base de datos. En el
ejemplo de código siguiente se implementa un método GetData que inicializa un componente
SqlDataAdapter y lo utiliza para rellenar un DataSet. Asegúrese de establecer la variable connectionString
en un valor que sea adecuado para la base de datos. Necesitará tener acceso a un servidor que tenga la base
de datos de ejemplo AdventureWorks de SQL Server instalada.
' Create the connection string for the AdventureWorks sample database.
Dim connectionString As String = "Data Source=localhost;Initial Catalog=AdventureWorks;" _
& "Integrated Security=true;"
' Create the command strings for querying the Contact table.
Dim contactSelectCommand As String = "SELECT ContactID, Title, FirstName, LastName,
EmailAddress, Phone FROM Person.Contact"
Catch ex As SqlException
MessageBox.Show(ex.Message)
End Try
End Sub
contactDataGridView.DataSource = contactBindingSource;
contactView = contactQuery.AsDataView();
contactDataGridView.DataSource = contactBindingSource
contactView = contactQuery.AsDataView()
Vea también
Enlace de datos y LINQ to DataSet
Depurar consultas de LINQ to DataSet
23/10/2019 • 6 minutes to read • Edit Online
Visual Studio admite la depuración de código de LINQ to DataSet. Sin embargo, hay algunas diferencias entre la
depuración de código LINQ to DataSet y el código no LINQ to DataSet administrado. La mayoría de las
características de depuración funcionan con instrucciones de LINQ to DataSet, incluida la ejecución paso a paso, el
establecimiento de puntos de interrupción y la visualización de resultados que se muestran en ventanas del
depurador. Sin embargo, la ejecución de consultas diferida en tiene algunos efectos secundarios que se deben
tener en cuenta durante la depuración LINQ to DataSet código y existen algunas limitaciones en el uso de editar y
continuar. En este tema se tratan aspectos de la depuración que son únicos en LINQ to DataSet comparados con el
código no LINQ to DataSet administrado.
Editar y continuar
Editar y continuar no admite cambios en las consultas de LINQ to DataSet. Si agrega, quita o cambia una
instrucción LINQ to DataSet durante una sesión de depuración, aparece un cuadro de diálogo que indica que el
cambio no es compatible con editar y continuar. En ese momento, puede deshacer los cambios o detener la sesión
de depuración y reiniciar una nueva sesión con el código revisado.
Además, editar y continuar no permite cambiar el tipo o el valor de una variable que se usa en una instrucción
LINQ to DataSet. De nuevo, puede deshacer los cambios o detener y reiniciar la sesión de depuración.
En Visual C# Studio, no puede usar editar y continuar en cualquier código en un método que contenga una
consulta LINQ to DataSet.
En Visual Basic en Visual Studio, puede usar editar y continuar en código no LINQ to DataSet, incluso en un método
que contenga una consulta LINQ to DataSet. Puede Agregar o quitar código antes de la instrucción LINQ to
DataSet, incluso si los cambios afectan al número de línea de la consulta LINQ to DataSet. La experiencia de
depuración de Visual Basic para el código que no es de LINQ to DataSet sigue siendo la misma que antes de que se
introdujera LINQ to DataSet. Sin embargo, no se puede cambiar, agregar o quitar una consulta LINQ to DataSet, a
menos que se detenga la depuración para aplicar los cambios.
Vea también
Depurar código administrado
Guía de programación
Seguridad (LINQ to DataSet)
23/10/2019 • 4 minutes to read • Edit Online
Entrada externa
A menudo, las aplicaciones obtienen entradas externas (de un usuario o de otro agente externo) y realizan acciones
basadas en dicha entrada. En el caso de LINQ to DataSet, la aplicación podría construir una consulta de una manera
determinada, basada en la entrada externa o usar la entrada externa en la consulta. LINQ to DataSet consultas
aceptan parámetros en todas partes donde se aceptan literales. Los desarrolladores de aplicaciones deben utilizar
consultas parametrizadas en lugar de insertar literales en la consulta procedentes de un agente externo.
Cualquier entrada derivada directa o indirectamente del usuario o de un agente externo puede inyectar contenido
que aproveche la sintaxis del lenguaje de destino para realizar acciones no autorizadas. Esto se conoce como
ataque de inyección de SQL porque en el patrón de ataque el idioma de destino es Transact-SQL. La entrada de
usuario inyectada directamente en la consulta se utiliza para quitar una tabla de base de datos, provocar un ataque
de denegación de servicio o cambiar la naturaleza de la operación que se está realizando. Aunque la composición
de consultas es posible en LINQ to DataSet, se realiza a través de la API del modelo de objetos. LINQ to DataSet
consultas no se componen mediante la manipulación o concatenación de cadenas, como en Transact-SQL, y no son
susceptibles de ataques de inyección de SQL en el sentido tradicional.
Vea también
Guía de programación
Ejemplos de LINQ to DataSet
23/10/2019 • 2 minutes to read • Edit Online
En esta sección se proporciona LINQ to DataSet ejemplos de programación que utilizan los operadores de
consulta estándar. El DataSet usado en estos ejemplos se rellena con el FillDataSet método, que se especifica
en cargar datos en un conjunto de datos. Para obtener más información, vea información general sobre
operadoresC#de consulta estándar () o información general sobre operadores de consulta estándar (Visual
Basic).
En esta sección
Ejemplos de expresiones de consultas
Contiene los siguientes ejemplos:
Proyección
Restricción
Creación de particiones
Ordenación
Operadores de elementos
Operadores de agregado
Operadores de combinación
Ejemplos de consultas basadas en métodos
Contiene los siguientes ejemplos:
Proyección
Particionamiento
Ordenación
Operadores Set
Operadores de conversión
Operadores de elementos
Operadores de agregado
Join
Ejemplos de operadores específicos de conjuntos de datos
Contiene ejemplos que demuestran cómo usar el método CopyToDataTable y la clase DataRowComparer.
Vea también
Guía de programación
Carga de datos en un conjunto de datos
Ejemplos de expresiones de consultas (LINQ to
DataSet)
23/10/2019 • 2 minutes to read • Edit Online
En esta sección
Proyección
Los ejemplos de este tema muestran cómo usar los métodos Select y SelectMany para consultar un DataSet.
Restricción
Los ejemplos de este tema muestran cómo usar el método Where para consultar un DataSet.
Creación de particiones
Los ejemplos de este tema muestran cómo usar los métodos Skip y Take para consultar un DataSet y particionar
los resultados.
Ordenación
Los ejemplos de este tema muestran cómo usar los métodos OrderBy, OrderByDescending, Reverse y
ThenByDescending para consultar un DataSet y ordenar los resultados.
Operadores de elementos
Los ejemplos de este tema muestran cómo utilizar los métodos First y ElementAt para obtener elementos DataRow
de un DataSet.
Operadores de agregado
Los ejemplos de este tema muestran cómo usar los métodos Average, Count, Max, Min y Sum para consultar
DataSet y agregar datos.
Operadores de combinación
Los ejemplos de este tema muestran cómo usar los métodos GroupJoin y Join para consultar un DataSet.
Vea también
Ejemplos de consultas basadas en métodos
Ejemplos de operadores específicos de conjuntos de datos
Ejemplos de LINQ to DataSet
Ejemplos de sintaxis de expresiones de consulta:
Proyección (LINQ to DataSet)
23/10/2019 • 6 minutes to read • Edit Online
Los ejemplos de este tema muestran cómo usar los métodos Select y SelectMany para consultar un DataSet
usando la sintaxis de expresión de consultas.
El FillDataSet método utilizado en estos ejemplos se especifica en cargar datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
En los ejemplos de este tema se usan using las siguientes / Imports instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, consulte Cómo Cree un proyecto de LINQ to DataSet en VisualStudio.
Seleccionar
Ejemplo
Este ejemplo utiliza Select para devolver todas las filas de la tabla Product y mostrar los nombres de producto.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
IEnumerable<DataRow> query =
from product in products.AsEnumerable()
select product;
Console.WriteLine("Product Names:");
foreach (DataRow p in query)
{
Console.WriteLine(p.Field<string>("Name"));
}
Ejemplo
Este ejemplo utiliza Select para devolver una secuencia de nombres de producto solamente.
IEnumerable<string> query =
from product in products.AsEnumerable()
select product.Field<string>("Name");
Console.WriteLine("Product Names:");
foreach (string productName in query)
{
Console.WriteLine(productName);
}
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)
Console.WriteLine("Product Names:")
For Each productName In query
Console.WriteLine(productName)
Next
SelectMany
Ejemplo
En este ejemplo se utiliza From …, … (el equivalente del método SelectMany) para seleccionar todos los pedidos en
los que TotalDue es inferior a 500,00.
var query =
from contact in contacts.AsEnumerable()
from order in orders.AsEnumerable()
where contact.Field<int>("ContactID") == order.Field<int>("ContactID")
&& order.Field<decimal>("TotalDue") < 500.00M
select new
{
ContactID = contact.Field<int>("ContactID"),
LastName = contact.Field<string>("LastName"),
FirstName = contact.Field<string>("FirstName"),
OrderID = order.Field<int>("SalesOrderID"),
Total = order.Field<decimal>("TotalDue")
};
Dim query = _
From contact In contacts.AsEnumerable() _
From order In orders.AsEnumerable() _
Where (contact.Field(Of Integer)("ContactID") = _
order.Field(Of Integer)("ContactID")) _
And (order.Field(Of Decimal)("TotalDue") < 500D) _
Select New With _
{ _
.ContactID = contact.Field(Of Integer)("ContactID"), _
.LastName = contact.Field(Of String)("LastName"), _
.FirstName = contact.Field(Of String)("FirstName"), _
.OrderID = order.Field(Of Integer)("SalesOrderID"), _
.TotalDue = order.Field(Of Decimal)("TotalDue") _
}
Ejemplo
En este ejemplo se utiliza From …, … (el equivalente del método SelectMany) para seleccionar todos los pedidos
efectuados a partir del 1 de octubre.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from contact in contacts.AsEnumerable()
from order in orders.AsEnumerable()
where contact.Field<int>("ContactID") == order.Field<int>("ContactID") &&
order.Field<DateTime>("OrderDate") >= new DateTime(2002, 10, 1)
select new
{
ContactID = contact.Field<int>("ContactID"),
LastName = contact.Field<string>("LastName"),
FirstName = contact.Field<string>("FirstName"),
OrderID = order.Field<int>("SalesOrderID"),
OrderDate = order.Field<DateTime>("OrderDate")
};
Dim query = _
From contact In contacts.AsEnumerable() _
From order In orders.AsEnumerable() _
Where contact.Field(Of Integer)("ContactID") = order.Field(Of Integer)("ContactID") And _
order.Field(Of DateTime)("OrderDate") >= New DateTime(2002, 10, 1) _
Select New With _
{ _
.ContactID = contact.Field(Of Integer)("ContactID"), _
.LastName = contact.Field(Of String)("LastName"), _
.FirstName = contact.Field(Of String)("FirstName"), _
.OrderID = order.Field(Of Integer)("SalesOrderID"), _
.OrderDate = order.Field(Of DateTime)("OrderDate") _
}
Ejemplo
En este ejemplo se utiliza From …, … (el equivalente al método SelectMany) para seleccionar todos los pedidos en
los que el total del pedido es superior a 10.000,00 y utiliza la asignación From para evitar que se solicite dos veces
el total.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from contact in contacts.AsEnumerable()
from order in orders.AsEnumerable()
let total = order.Field<decimal>("TotalDue")
where contact.Field<int>("ContactID") == order.Field<int>("ContactID") &&
total >= 10000.0M
select new
{
ContactID = contact.Field<int>("ContactID"),
LastName = contact.Field<string>("LastName"),
OrderID = order.Field<int>("SalesOrderID"),
total
};
foreach (var order in query)
{
Console.WriteLine("Contact ID: {0} Last name: {1} Order ID: {2} Total: {3}",
order.ContactID, order.LastName, order.OrderID, order.total);
}
Dim query = _
From contact In contacts.AsEnumerable() _
From order In orders.AsEnumerable() _
Let total = order.Field(Of Decimal)("TotalDue") _
Where contact.Field(Of Integer)("ContactID") = order.Field(Of Integer)("ContactID") And _
total >= 10000D _
Select New With _
{ _
.ContactID = contact.Field(Of Integer)("ContactID"), _
.LastName = contact.Field(Of String)("LastName"), _
.OrderID = order.Field(Of Integer)("SalesOrderID"), _
.OrderDate = order.Field(Of DateTime)("OrderDate"), _
total _
}
Vea también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Standard Query Operators Overview (C#) (Información general sobre operadores de consulta estándar (C#))
Información general sobre operadores de consulta estándar (Visual Basic)
Ejemplos de sintaxis de expresiones de consulta:
Restricción (LINQ to DataSet)
21/03/2020 • 4 minutes to read • Edit Online
Los ejemplos de este tema muestran cómo utilizar el método Where para consultar DataSet utilizando sintaxis de
expresión de consultas.
El FillDataSet método utilizado en estos ejemplos se especifica en Carga de datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
Los ejemplos de este using / Imports tema utilizan las siguientes instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Para obtener más información, vea Cómo: crear un proyecto LINQ to DataSet en Visual Studio.
Where
Ejemplo
Este ejemplo devuelve todos los pedidos en línea.
var query =
from order in orders.AsEnumerable()
where order.Field<bool>("OnlineOrderFlag") == true
select new
{
SalesOrderID = order.Field<int>("SalesOrderID"),
OrderDate = order.Field<DateTime>("OrderDate"),
SalesOrderNumber = order.Field<string>("SalesOrderNumber")
};
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of Boolean)("OnlineOrderFlag") = True _
Select New With { _
.SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
.OrderDate = order.Field(Of DateTime)("OrderDate"), _
.SalesOrderNumber = order.Field(Of String)("SalesOrderNumber") _
}
Ejemplo
Este ejemplo devuelve los pedidos en los que la cantidad de pedido es superior a 2 e inferior a 6.
var query =
from order in orders.AsEnumerable()
where order.Field<Int16>("OrderQty") > 2 &&
order.Field<Int16>("OrderQty") < 6
select new
{
SalesOrderID = (int)order.Field<int>("SalesOrderID"),
OrderQty = order.Field<Int16>("OrderQty")
};
Dim query = _
From order In orders.AsEnumerable() _
Where order.Field(Of Short)("OrderQty") > 2 And _
order.Field(Of Short)("OrderQty") < 6 _
Select New With _
{ _
.SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
.OrderQty = order.Field(Of Short)("OrderQty") _
}
Ejemplo
Este ejemplo devuelve todos los productos de color rojo.
var query =
from product in products.AsEnumerable()
where product.Field<string>("Color") == "Red"
select new
{
Name = product.Field<string>("Name"),
ProductNumber = product.Field<string>("ProductNumber"),
ListPrice = product.Field<Decimal>("ListPrice")
};
Dim query = _
From product In products.AsEnumerable() _
Where product.Field(Of String)("Color") = "Red" _
Select New With _
{ _
.Name = product.Field(Of String)("Name"), _
.ProductNumber = product.Field(Of String)("ProductNumber"), _
.ListPrice = product.Field(Of Decimal)("ListPrice") _
}
Ejemplo
En este ejemplo se utiliza el método Where para buscar pedidos efectuados con posterioridad al 1 de diciembre de
2002 y, a continuación, se utiliza el método GetChildRows para obtener los detalles de cada pedido.
IEnumerable<DataRow> query =
from order in orders.AsEnumerable()
where order.Field<DateTime>("OrderDate") >= new DateTime(2002, 12, 1)
select order;
Consulte también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Información general sobre operadores de consulta estándar (C#)
Información general sobre operadores de consulta estándar (Visual Basic)
Ejemplos de sintaxis de expresiones de consulta:
Creación de particiones (LINQ to DataSet)
23/10/2019 • 3 minutes to read • Edit Online
Los ejemplos de este tema muestran cómo usar los métodos Skip y Take para consultar un DataSet usando la
sintaxis de expresión de consultas.
El FillDataSet método utilizado en estos ejemplos se especifica en cargar datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
En los ejemplos de este tema se usan using las siguientes / Imports instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, consulte Cómo Cree un proyecto de LINQ to DataSet en VisualStudio.
Skip
Ejemplo
En este ejemplo se utiliza el método Skip para obtener las dos primeras direcciones de Seattle.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query = (
from address in addresses.AsEnumerable()
from order in orders.AsEnumerable()
where address.Field<int>("AddressID") == order.Field<int>("BillToAddressID")
&& address.Field<string>("City") == "Seattle"
select new
{
City = address.Field<string>("City"),
OrderID = order.Field<int>("SalesOrderID"),
OrderDate = order.Field<DateTime>("OrderDate")
}).Skip(2);
Dim query = ( _
From address In addresses.AsEnumerable() _
From order In orders.AsEnumerable() _
Where (address.Field(Of Integer)("AddressID") = _
order.Field(Of Integer)("BillToAddressID")) _
And address.Field(Of String)("City") = "Seattle" _
Select New With _
{ _
.City = address.Field(Of String)("City"), _
.OrderID = order.Field(Of Integer)("SalesOrderID"), _
.OrderDate = order.Field(Of DateTime)("OrderDate") _
}).Skip(2)
Take
Ejemplo
En este ejemplo se utiliza el método Take para obtener las tres primeras direcciones de Seattle.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query = (
from address in addresses.AsEnumerable()
from order in orders.AsEnumerable()
where address.Field<int>("AddressID") == order.Field<int>("BillToAddressID")
&& address.Field<string>("City") == "Seattle"
select new
{
City = address.Field<string>("City"),
OrderID = order.Field<int>("SalesOrderID"),
OrderDate = order.Field<DateTime>("OrderDate")
}).Take(3);
Dim query = ( _
From address In addresses.AsEnumerable() _
From order In orders.AsEnumerable() _
Where (address.Field(Of Integer)("AddressID") = _
order.Field(Of Integer)("BillToAddressID")) _
And address.Field(Of String)("City") = "Seattle" _
Select New With _
{ _
.City = address.Field(Of String)("City"), _
.OrderID = order.Field(Of Integer)("SalesOrderID"), _
.OrderDate = order.Field(Of DateTime)("OrderDate") _
}).Take(3)
Vea también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Standard Query Operators Overview (C#) (Información general sobre operadores de consulta estándar (C#))
Información general sobre operadores de consulta estándar (Visual Basic)
Ejemplos de sintaxis de expresiones de consulta:
Ordenación (LINQ to DataSet)
23/10/2019 • 5 minutes to read • Edit Online
Los ejemplos de este tema muestran cómo se utilizan los métodos OrderBy, OrderByDescending, Reverse y
ThenByDescending para consultar DataSet y ordenar los resultados utilizando la sintaxis de expresiones de
consultas.
El FillDataSet método utilizado en estos ejemplos se especifica en cargar datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
En los ejemplos de este tema se usan using las siguientes / Imports instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, vea Cómo: Cree un proyecto de LINQ to DataSet en VisualStudio.
OrderBy
Ejemplo
En este ejemplo se utiliza OrderBy para devolver una lista de contactos organizados por apellido.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
IEnumerable<DataRow> query =
from contact in contacts.AsEnumerable()
orderby contact.Field<string>("LastName")
select contact;
Dim query = _
From contact In contacts.AsEnumerable() _
Select contact _
Order By contact.Field(Of String)("LastName")
Ejemplo
En este ejemplo se utiliza OrderBy para ordenar una lista de contactos por longitud del apellido.
IEnumerable<DataRow> query =
from contact in contacts.AsEnumerable()
orderby contact.Field<string>("LastName").Length
select contact;
Dim query = _
From contact In contacts.AsEnumerable() _
Select contact _
Order By contact.Field(Of String)("LastName").Length
OrderByDescending
Ejemplo
En este ejemplo se utiliza orderby… descending ( Order By … Descending ), equivalente al método
OrderByDescending, para ordenar el precio de venta de mayor a menor.
IEnumerable<Decimal> query =
from product in products.AsEnumerable()
orderby product.Field<Decimal>("ListPrice") descending
select product.Field<Decimal>("ListPrice");
Dim query = _
From product In products.AsEnumerable() _
Select product _
Order By product.Field(Of Decimal)("ListPrice") Descending
IEnumerable<DataRow> query = (
from order in orders.AsEnumerable()
where order.Field<DateTime>("OrderDate") < new DateTime(2002, 02, 20)
select order).Reverse();
Console.WriteLine("A backwards list of orders where OrderDate < Feb 20, 2002");
foreach (DataRow order in query)
{
Console.WriteLine(order.Field<DateTime>("OrderDate"));
}
Dim query = ( _
From order In orders.AsEnumerable() _
Where order.Field(Of DateTime)("OrderDate") < New DateTime(2002, 2, 20) _
Select order).Reverse()
Console.WriteLine("A backwards list of orders where OrderDate < Feb 20, 2002")
ThenByDescending
Ejemplo
En este ejemplo se utiliza OrderBy… Descending , que es equivalente al método ThenByDescending, para ordenar
una lista de productos, primero por nombre y después por precio de venta, de mayor a menor.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
IEnumerable<DataRow> query =
from product in products.AsEnumerable()
orderby product.Field<string>("Name"),
product.Field<Decimal>("ListPrice") descending
select product;
Dim query = _
From product In products.AsEnumerable() _
Order By product.Field(Of String)("Name"), _
product.Field(Of Decimal)("ListPrice") Descending _
Select product
Vea también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Standard Query Operators Overview (C#) (Información general sobre operadores de consulta estándar (C#))
Información general sobre operadores de consulta estándar (Visual Basic)
Ejemplos de sintaxis de expresiones de consulta:
Operadores de elementos (LINQ to DataSet)
23/10/2019 • 2 minutes to read • Edit Online
Los ejemplos de este tema muestran cómo usar los métodos First y ElementAt para obtener elementos DataRow
de un DataSet usando la sintaxis de expresiones de consulta.
El FillDataSet método utilizado en estos ejemplos se especifica en cargar datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
En los ejemplos de este tema se usan using las siguientes / Imports instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, vea Cómo: Cree un proyecto de LINQ to DataSet en VisualStudio.
ElementAt
Ejemplo
Este ejemplo usa el método ElementAt para recuperar la quinta dirección donde PostalCode == "M4B 1V7".
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var fifthAddress = (
from address in addresses.AsEnumerable()
where address.Field<string>("PostalCode") == "M4B 1V7"
select address.Field<string>("AddressLine1"))
.ElementAt(5);
Dim fifthAddress = ( _
From address In addresses.AsEnumerable() _
Where address.Field(Of String)("PostalCode") = "M4B 1V7" _
Select address.Field(Of String)("AddressLine1")).ElementAt(5)
Primero
Ejemplo
Este ejemplo usar el método First para devolver el primer contacto cuyo nombre es 'Brooke'.
DataRow query = (
from contact in contacts.AsEnumerable()
where (string)contact["FirstName"] == "Brooke"
select contact)
.First();
Dim query = ( _
From contact In contacts.AsEnumerable() _
Where contact.Field(Of String)("FirstName") = "Brooke" _
Select contact).First()
Vea también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Standard Query Operators Overview (C#) (Información general sobre operadores de consulta estándar (C#))
Información general sobre operadores de consulta estándar (Visual Basic)
Ejemplos de sintaxis de expresiones de consulta:
Operadores de agregado (LINQ to DataSet)
23/10/2019 • 11 minutes to read • Edit Online
Los ejemplos de este tema muestran cómo utilizar los métodos Average, Count, Max, Min y Sum para consultar un
DataSet y agregar datos utilizando sintaxis de expresiones de consulta.
El FillDataSet método utilizado en estos ejemplos se especifica en cargar datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
En los ejemplos de este tema se usan using las siguientes / Imports instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, consulte Cómo Cree un proyecto de LINQ to DataSet en VisualStudio.
Average
Ejemplo
En este ejemplo se utiliza el método Average para encontrar el precio de venta promedio de cada estilo de
productos.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
Dim query = _
From product In products _
Group product By style = product.Field(Of String)("Style") Into g = Group _
Select New With _
{ _
.Style = style, _
.AverageListPrice = g.Average(Function(product) _
product.Field(Of Decimal)("ListPrice")) _
}
Ejemplo
En este ejemplo se utiliza Average para obtener el importe total a pagar promedio para cada id. de contacto.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from order in orders.AsEnumerable()
group order by order.Field<Int32>("ContactID") into g
select new
{
Category = g.Key,
averageTotalDue =
g.Average(order => order.Field<decimal>("TotalDue"))
};
Dim query = _
From order In orders.AsEnumerable() _
Group order By contactID = order.Field(Of Int32)("ContactID") Into g = Group _
Select New With _
{ _
.Category = contactID, _
.averageTotalDue = g.Average(Function(order) order. _
Field(Of Decimal)("TotalDue")) _
}
Ejemplo
En este ejemplo se utiliza Average para obtener los pedidos con el TotalDue promedio para cada de contacto.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from order in orders.AsEnumerable()
group order by order.Field<Int32>("ContactID") into g
let averageTotalDue = g.Average(order => order.Field<decimal>("TotalDue"))
select new
{
Category = g.Key,
CheapestProducts =
g.Where(order => order.Field<decimal>("TotalDue") ==
averageTotalDue)
};
Dim query = _
From order In orders.AsEnumerable() _
Group order By contactID = order.Field(Of Int32)("ContactID") Into g = Group _
Let averageTotalDue = g.Average(Function(order) order.Field(Of Decimal)("TotalDue")) _
Select New With _
{ _
.Category = contactID, _
.CheapestProducts = g.Where(Function(order) order. _
Field(Of Decimal)("TotalDue") = averageTotalDue) _
}
Número
Ejemplo
En este ejemplo se utiliza Count para devolver una lista de id. de contactos y el número de pedidos que tiene cada
uno de ellos.
Dim query = _
From contact In contacts.AsEnumerable() _
Select New With _
{ _
.ContactID = contact.Field(Of Integer)("ContactID"), _
.OrderCount = contact.GetChildRows("SalesOrderContact").Count() _
}
Ejemplo
En este ejemplo se agrupan los productos por colores y se utiliza Count para devolver el número de productos de
cada grupo de color.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from product in products.AsEnumerable()
group product by product.Field<string>("Color") into g
select new { Color = g.Key, ProductCount = g.Count() };
Dim query = _
From product In products.AsEnumerable() _
Group product By color = product.Field(Of String)("Color") Into g = Group _
Select New With {.Color = color, .ProductCount = g.Count()}
Máx.
Ejemplo
En este ejemplo se utiliza el método Max para obtener el mayor importe total a pagar de cada id. de contacto.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from order in orders.AsEnumerable()
group order by order.Field<Int32>("ContactID") into g
select new
{
Category = g.Key,
maxTotalDue =
g.Max(order => order.Field<decimal>("TotalDue"))
};
Dim query = _
From order In orders.AsEnumerable() _
Group order By contactID = order.Field(Of Int32)("ContactID") Into g = Group _
Select New With _
{ _
.Category = contactID, _
.maxTotalDue = _
g.Max(Function(order) order.Field(Of Decimal)("TotalDue")) _
}
For Each order In query
Console.WriteLine("ContactID = {0} " & vbTab & _
" Maximum TotalDue = {1}", _
order.Category, order.maxTotalDue)
Next
Ejemplo
En este ejemplo se utiliza el método Max para obtener los pedidos con el TotalDue mayor de cada id. contacto.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from order in orders.AsEnumerable()
group order by order.Field<Int32>("ContactID") into g
let maxTotalDue = g.Max(order => order.Field<decimal>("TotalDue"))
select new
{
Category = g.Key,
CheapestProducts =
g.Where(order => order.Field<decimal>("TotalDue") ==
maxTotalDue)
};
Dim query = _
From order In orders.AsEnumerable() _
Group order By contactID = order.Field(Of Int32)("ContactID") Into g = Group _
Let maxTotalDue = g.Max(Function(order) order.Field(Of Decimal)("TotalDue")) _
Select New With _
{ _
.Category = contactID, _
.CheapestProducts = _
g.Where(Function(order) order. _
Field(Of Decimal)("TotalDue") = maxTotalDue) _
}
Mín.
Ejemplo
En este ejemplo se utiliza el método Min para obtener el menor importe total a pagar de cada id. de contacto.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from order in orders.AsEnumerable()
group order by order.Field<Int32>("ContactID") into g
select new
{
Category = g.Key,
smallestTotalDue =
g.Min(order => order.Field<decimal>("TotalDue"))
};
Dim query = _
From order In orders.AsEnumerable() _
Group order By contactID = order.Field(Of Int32)("ContactID") Into g = Group _
Select New With _
{ _
.Category = contactID, _
.smallestTotalDue = g.Min(Function(order) _
order.Field(Of Decimal)("TotalDue")) _
}
Ejemplo
En este ejemplo se utiliza el método Min para obtener el pedido con el menor importe total a pagar de cada
contacto.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from order in orders.AsEnumerable()
group order by order.Field<Int32>("ContactID") into g
let minTotalDue = g.Min(order => order.Field<decimal>("TotalDue"))
select new
{
Category = g.Key,
smallestTotalDue =
g.Where(order => order.Field<decimal>("TotalDue") ==
minTotalDue)
};
Dim query = _
From order In orders.AsEnumerable() _
Group order By contactID = order.Field(Of Int32)("ContactID") Into g = Group _
Let minTotalDue = g.Min(Function(order) order.Field(Of Decimal)("TotalDue")) _
Select New With _
{ _
.Category = contactID, _
.smallestTotalDue = g.Where(Function(order) order. _
Field(Of Decimal)("TotalDue") = minTotalDue) _
}
Sum
Ejemplo
En este ejemplo se utiliza el método Sum para obtener el importe total a pagar de cada id. de contacto.
var query =
from order in orders.AsEnumerable()
group order by order.Field<Int32>("ContactID") into g
select new
{
Category = g.Key,
TotalDue = g.Sum(order => order.Field<decimal>("TotalDue")),
};
foreach (var order in query)
{
Console.WriteLine("ContactID = {0} \t TotalDue sum = {1}",
order.Category, order.TotalDue);
}
Dim query = _
From order In orders.AsEnumerable() _
Group order By contactID = order.Field(Of Int32)("ContactID") Into g = Group _
Select New With _
{ _
.Category = contactID, _
.TotalDue = g.Sum(Function(order) order. _
Field(Of Decimal)("TotalDue")) _
}
Vea también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Standard Query Operators Overview (C#) (Información general sobre operadores de consulta estándar (C#))
Información general sobre operadores de consulta estándar (Visual Basic)
Ejemplos de sintaxis de expresiones de consulta:
Operadores de combinación (LINQ to DataSet)
23/10/2019 • 5 minutes to read • Edit Online
La combinación es una operación importante de las consultas dirigidas a orígenes de datos que no tienen
relaciones navegables entre ellos, como las tablas de bases de datos relacionales. Una combinación de dos
orígenes de datos es la asociación de objetos en un origen de datos con objetos que comparten un atributo común
en el otro origen de datos. Para obtener más información, vea información general sobre operadoresC#de consulta
estándar () o información general sobre operadores de consulta estándar (Visual Basic).
Los ejemplos de este tema muestran cómo usar los métodos GroupJoin y Join para consultar un DataSet usando la
sintaxis de expresión de consultas.
El FillDataSet método utilizado en estos ejemplos se especifica en cargar datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
En los ejemplos de este tema se usan using las siguientes / Imports instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, consulte Cómo Cree un proyecto de LINQ to DataSet en VisualStudio.
GroupJoin
Ejemplo
Este ejemplo realiza un GroupJoin en las tablas SalesOrderHeader y SalesOrderDetail para buscar el número de
pedidos por cliente. Una combinación de grupo es el equivalente a una combinación externa izquierda, que
devuelve cada elemento del primer origen de datos (izquierdo), incluso si no hay elementos correlacionados en el
otro origen de datos.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from order in orders
join detail in details
on order.Field<int>("SalesOrderID")
equals detail.Field<int>("SalesOrderID") into ords
select new
{
CustomerID =
order.Field<int>("SalesOrderID"),
ords = ords.Count()
};
Dim query = _
From order In orders _
Group Join detail In details _
On order.Field(Of Integer)("SalesOrderID") _
Equals detail.Field(Of Integer)("SalesOrderID") Into ords = Group _
Select New With _
{ _
.CustomerID = order.Field(Of Integer)("SalesOrderID"), _
.ords = ords.Count() _
}
Ejemplo
Este ejemplo realiza un GroupJoin en las tablas Contact y SalesOrderHeader . Una combinación de grupo es el
equivalente a una combinación externa izquierda, que devuelve cada elemento del primer origen de datos
(izquierdo), incluso si no hay elementos correlacionados en el otro origen de datos.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from contact in contacts.AsEnumerable()
join order in orders.AsEnumerable()
on contact.Field<Int32>("ContactID") equals
order.Field<Int32>("ContactID")
select new
{
ContactID = contact.Field<Int32>("ContactID"),
SalesOrderID = order.Field<Int32>("SalesOrderID"),
FirstName = contact.Field<string>("FirstName"),
Lastname = contact.Field<string>("Lastname"),
TotalDue = order.Field<decimal>("TotalDue")
};
Dim query = _
From contact In contacts.AsEnumerable(), order In orders.AsEnumerable() _
Where (contact.Field(Of Integer)("ContactID") = _
order.Field(Of Integer)("ContactID")) _
Select New With _
{ _
.ContactID = contact.Field(Of Integer)("ContactID"), _
.SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
.FirstName = contact.Field(Of String)("FirstName"), _
.Lastname = contact.Field(Of String)("Lastname"), _
.TotalDue = order.Field(Of Decimal)("TotalDue") _
}
var query =
from order in orders.AsEnumerable()
join detail in details.AsEnumerable()
on order.Field<int>("SalesOrderID") equals
detail.Field<int>("SalesOrderID")
where order.Field<bool>("OnlineOrderFlag") == true
&& order.Field<DateTime>("OrderDate").Month == 8
select new
{
SalesOrderID =
order.Field<int>("SalesOrderID"),
SalesOrderDetailID =
detail.Field<int>("SalesOrderDetailID"),
OrderDate =
order.Field<DateTime>("OrderDate"),
ProductID =
detail.Field<int>("ProductID")
};
Dim query = _
From order In orders.AsEnumerable() _
Join detail In details.AsEnumerable() _
On order.Field(Of Integer)("SalesOrderID") Equals _
detail.Field(Of Integer)("SalesOrderID") _
Where order.Field(Of Boolean)("OnlineOrderFlag") = True And _
order.Field(Of DateTime)("OrderDate").Month = 8 _
Select New With _
{ _
.SalesOrderID = order.Field(Of Integer)("SalesOrderID"), _
.SalesOrderDetailID = detail.Field(Of Integer)("SalesOrderDetailID"), _
.OrderDate = order.Field(Of DateTime)("OrderDate"), _
.ProductID = detail.Field(Of Integer)("ProductID") _
}
Vea también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Standard Query Operators Overview (C#) (Información general sobre operadores de consulta estándar (C#))
Información general sobre operadores de consulta estándar (Visual Basic)
Ejemplos de consultas basadas en métodos (LINQ to
DataSet)
23/10/2019 • 2 minutes to read • Edit Online
En esta sección se proporciona LINQ to DataSet ejemplos de programación de la sintaxis de consulta basada en
métodos que usan los operadores de consulta estándar. El DataSet usado en estos ejemplos se rellena con el
FillDataSet método, que se especifica en cargar datos en un conjunto de datos. Para obtener más información,
vea información general sobre operadoresC#de consulta estándar () o información general sobre operadores de
consulta estándar (Visual Basic).
En esta sección
Proyección
Los ejemplos de este tema muestran cómo usar los métodos Select y SelectMany para consultar un DataSet.
Creación de particiones
Los ejemplos de este tema muestran cómo usar los métodos Skip y Take para consultar un DataSet y particionar
los resultados.
Ordenación
Los ejemplos de este tema muestran cómo usar los métodos OrderBy, OrderByDescending, Reverse y
ThenByDescending para consultar un DataSet y ordenar los resultados.
Operadores Set
Los ejemplos de este tema muestran cómo usar los operadores Distinct, Except, Intersect y Union para operaciones
de comparación basadas en valores en conjuntos de filas de datos.
Operadores de conversión
Los ejemplos de este tema muestran cómo usar los métodos ToArray, ToDictionary y ToList para ejecutar
inmediatamente una expresión de consulta.
Operadores de elementos
Los ejemplos de este tema muestran cómo utilizar los métodos First y ElementAt para obtener elementos DataRow
de un DataSet.
Operadores de agregado
Los ejemplos de este tema muestran cómo usar los métodos Average, Count, Max, Min y Sum para consultar
DataSet y agregar datos.
Join
Los ejemplos de este tema muestran cómo usar los métodos GroupJoin y Join para consultar un DataSet.
Vea también
Ejemplos de expresiones de consultas
Ejemplos de operadores específicos de conjuntos de datos
Ejemplos de LINQ to DataSet
Ejemplos de sintaxis de consulta basada en métodos:
Proyección (LINQ to DataSet)
23/10/2019 • 4 minutes to read • Edit Online
Los ejemplos de este tema muestran cómo usar los métodos Select y SelectMany para consultar DataSet usando la
sintaxis de consulta basada en métodos.
El FillDataSet método utilizado en estos ejemplos se especifica en cargar datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
En los ejemplos de este tema se usan using las siguientes / Imports instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, vea Cómo: Cree un proyecto de LINQ to DataSet en VisualStudio.
Seleccionar
Ejemplo
En este ejemplo se utiliza el método Select para proyectar las propiedades Name , ProductNumber y ListPrice en
una secuencia de tipos anónimos. El nombre de la propiedad ListPrice se cambia a Price en el tipo resultante.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
Console.WriteLine("Product Info:");
foreach (var productInfo in query)
{
Console.WriteLine("Product name: {0} Product number: {1} List price: ${2} ",
productInfo.ProductName, productInfo.ProductNumber, productInfo.Price);
}
Console.WriteLine("Product Info:")
For Each product In query
Console.Write("Product name: " & product.ProductName)
Console.Write("Product number: " & product.ProductNumber)
Console.WriteLine("List price: $ " & product.Price)
Next
SelectMany
Ejemplo
En este ejemplo se utiliza el método SelectMany para seleccionar todos los pedidos en los que TotalDue es
inferior a 500,00.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
contacts.SelectMany(
contact => orders.Where(order =>
(contact.Field<Int32>("ContactID") == order.Field<Int32>("ContactID"))
&& order.Field<decimal>("TotalDue") < 500.00M)
.Select(order => new
{
ContactID = contact.Field<int>("ContactID"),
LastName = contact.Field<string>("LastName"),
FirstName = contact.Field<string>("FirstName"),
OrderID = order.Field<int>("SalesOrderID"),
Total = order.Field<decimal>("TotalDue")
}));
Dim query = _
contacts.SelectMany( _
Function(contact) orders.Where(Function(order) _
(contact.Field(Of Int32)("ContactID") = order.Field(Of Int32)("ContactID")) _
And order.Field(Of Decimal)("TotalDue") < 500D) _
.Select(Function(order) New With _
{ _
.ContactID = contact.Field(Of Integer)("ContactID"), _
.LastName = contact.Field(Of String)("LastName"), _
.FirstName = contact.Field(Of String)("FirstName"), _
.OrderID = order.Field(Of Integer)("SalesOrderID"), _
.Total = order.Field(Of Decimal)("TotalDue") _
}))
Ejemplo
En este ejemplo se utiliza el método SelectMany para seleccionar todos los pedidos efectuados a partir del 1 de
octubre.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
contacts.SelectMany(
contact => orders.Where(order =>
(contact.Field<Int32>("ContactID") == order.Field<Int32>("ContactID"))
&& order.Field<DateTime>("OrderDate") >= new DateTime(2002, 10, 1))
.Select(order => new
{
ContactID = contact.Field<int>("ContactID"),
LastName = contact.Field<string>("LastName"),
FirstName = contact.Field<string>("FirstName"),
OrderID = order.Field<int>("SalesOrderID"),
OrderDate = order.Field<DateTime>("OrderDate")
}));
Dim query = _
contacts.SelectMany( _
Function(contact) orders.Where(Function(order) _
(contact.Field(Of Int32)("ContactID") = order.Field(Of Int32)("ContactID")) _
And order.Field(Of DateTime)("OrderDate") >= New DateTime(2002, 10, 1)) _
.Select(Function(order) New With _
{ _
.ContactID = contact.Field(Of Integer)("ContactID"), _
.LastName = contact.Field(Of String)("LastName"), _
.FirstName = contact.Field(Of String)("FirstName"), _
.OrderID = order.Field(Of Integer)("SalesOrderID"), _
.OrderDate = order.Field(Of DateTime)("OrderDate") _
}))
Vea también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Standard Query Operators Overview (C#) (Información general sobre operadores de consulta estándar (C#))
Información general sobre operadores de consulta estándar (Visual Basic)
Ejemplos de sintaxis de consulta basada en métodos:
Creación de particiones (LINQ
23/10/2019 • 6 minutes to read • Edit Online
Los ejemplos de este tema muestran cómo usar los métodos Skip, SkipWhile, Take y TakeWhile para consultar un
DataSet usando la sintaxis de expresión de consultas.
El FillDataSet método utilizado en estos ejemplos se especifica en cargar datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
En los ejemplos de este tema se usan using las siguientes / Imports instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, consulte Cómo Cree un proyecto de LINQ to DataSet en VisualStudio.
Skip
Ejemplo
En este ejemplo se utiliza el método Skip para obtener todos los contactos menos los cinco primeros de la tabla
Contact .
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
Ejemplo
En este ejemplo se utiliza el método Skip para obtener las dos primeras direcciones de Seattle.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query = (
from address in addresses.AsEnumerable()
from order in orders.AsEnumerable()
where address.Field<int>("AddressID") == order.Field<int>("BillToAddressID")
&& address.Field<string>("City") == "Seattle"
select new
{
City = address.Field<string>("City"),
OrderID = order.Field<int>("SalesOrderID"),
OrderDate = order.Field<DateTime>("OrderDate")
}).Skip(2);
Dim query = ( _
From address In addresses.AsEnumerable() _
From order In orders.AsEnumerable() _
Where (address.Field(Of Integer)("AddressID") = _
order.Field(Of Integer)("BillToAddressID")) _
And address.Field(Of String)("City") = "Seattle" _
Select New With _
{ _
.City = address.Field(Of String)("City"), _
.OrderID = order.Field(Of Integer)("SalesOrderID"), _
.OrderDate = order.Field(Of DateTime)("OrderDate") _
}).Skip(2)
SkipWhile
Ejemplo
En este ejemplo se utilizan los métodos OrderBy y SkipWhile para devolver productos de la tabla Product con un
precio de venta superior a 300,00.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
IEnumerable<DataRow> skipWhilePriceLessThan300 =
products.AsEnumerable()
.OrderBy(listprice => listprice.Field<decimal>("ListPrice"))
.SkipWhile(product => product.Field<decimal>("ListPrice") < 300.00M);
Take
Ejemplo
En este ejemplo se utiliza el método Take para obtener únicamente los cinco primeros contactos de la tabla
Contact .
Console.WriteLine("First 5 contacts:");
foreach (DataRow contact in first5Contacts)
{
Console.WriteLine("Title = {0} \t FirstName = {1} \t Lastname = {2}",
contact.Field<string>("Title"),
contact.Field<string>("FirstName"),
contact.Field<string>("Lastname"));
}
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)
Console.WriteLine("First 5 contacts:")
For Each contact In first5Contacts
Console.Write("Title = " & contact.Field(Of String)("Title"))
Console.Write(vbTab & "FirstName = " & contact.Field(Of String)("FirstName"))
Console.WriteLine(vbTab & "LastName = " & contact.Field(Of String)("LastName"))
Next
Ejemplo
En este ejemplo se utiliza el método Take para obtener las tres primeras direcciones de Seattle.
var query = (
from address in addresses.AsEnumerable()
from order in orders.AsEnumerable()
where address.Field<int>("AddressID") == order.Field<int>("BillToAddressID")
&& address.Field<string>("City") == "Seattle"
select new
{
City = address.Field<string>("City"),
OrderID = order.Field<int>("SalesOrderID"),
OrderDate = order.Field<DateTime>("OrderDate")
}).Take(3);
Dim query = ( _
From address In addresses.AsEnumerable() _
From order In orders.AsEnumerable() _
Where (address.Field(Of Integer)("AddressID") = _
order.Field(Of Integer)("BillToAddressID")) _
And address.Field(Of String)("City") = "Seattle" _
Select New With _
{ _
.City = address.Field(Of String)("City"), _
.OrderID = order.Field(Of Integer)("SalesOrderID"), _
.OrderDate = order.Field(Of DateTime)("OrderDate") _
}).Take(3)
TakeWhile
Ejemplo
En este ejemplo se utilizan los métodos OrderBy y TakeWhile para devolver de la tabla productos Product con un
precio de venta inferior a 300,00.
IEnumerable<DataRow> takeWhileListPriceLessThan300 =
products.AsEnumerable()
.OrderBy(listprice => listprice.Field<decimal>("ListPrice"))
.TakeWhile(product => product.Field<decimal>("ListPrice") < 300.00M);
Vea también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Standard Query Operators Overview (C#) (Información general sobre operadores de consulta estándar (C#))
Información general sobre operadores de consulta estándar (Visual Basic)
Ejemplos de sintaxis de consulta basada en métodos:
Ordenación (LINQ to DataSet)
23/10/2019 • 3 minutes to read • Edit Online
Los ejemplos de este tema muestran cómo se utilizan los métodos OrderBy, Reverse y ThenBy para consultar
DataSet y ordenar los resultados utilizando la sintaxis de consulta basada en métodos.
El FillDataSet método utilizado en estos ejemplos se especifica en cargar datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
En los ejemplos de este tema se usan using las siguientes / Imports instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, consulte Cómo Cree un proyecto de LINQ to DataSet en VisualStudio.
OrderBy
Ejemplo
Este ejemplo utiliza el método OrderBy con un comparador personalizado para realizar una ordenación con
distinción de mayúsculas y minúsculas de apellidos.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
IEnumerable<DataRow> query =
contacts.AsEnumerable().OrderBy(contact => contact.Field<string>("LastName"),
new CaseInsensitiveComparer());
Reverse
Ejemplo
En este ejemplo se utiliza el método Reverse para crear una lista de pedidos en los que OrderDate es anterior al 20
de febrero de 2002.
IEnumerable<DataRow> query = (
from order in orders.AsEnumerable()
where order.Field<DateTime>("OrderDate") < new DateTime(2002, 02, 20)
select order).Reverse();
Console.WriteLine("A backwards list of orders where OrderDate < Feb 20, 2002");
foreach (DataRow order in query)
{
Console.WriteLine(order.Field<DateTime>("OrderDate"));
}
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)
Dim query = ( _
From order In orders.AsEnumerable() _
Where order.Field(Of DateTime)("OrderDate") < New DateTime(2002, 2, 20) _
Select order).Reverse()
Console.WriteLine("A backwards list of orders where OrderDate < Feb 20, 2002")
ThenBy
Ejemplo
En este ejemplo se utilizan los métodos OrderBy y ThenBy con un comparador personalizado para ordenar
primero por precio de venta y después realizar una ordenación con distinción de mayúsculas y minúsculas en
orden descendente de nombres de producto.
IEnumerable<DataRow> query =
products.AsEnumerable().OrderBy(product => product.Field<Decimal>("ListPrice"))
.ThenBy(product => product.Field<string>("Name"),
new CaseInsensitiveComparer());
Vea también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Standard Query Operators Overview (C#) (Información general sobre operadores de consulta estándar (C#))
Información general sobre operadores de consulta estándar (Visual Basic)
Ejemplos de sintaxis de consulta basada en métodos:
Operadores de conjuntos (LINQ to DataSet)
23/10/2019 • 6 minutes to read • Edit Online
En los ejemplos de este tema se muestra cómo usar Distinctlos Exceptoperadores Intersect,, Union y para realizar
operaciones de comparación basadas en valores en conjuntos de filas de datos. Cargar datos en un conjunto de
datos ; vea comparar filas de datos para DataRowComparerobtener más información sobre.
El FillDataSet método utilizado en estos ejemplos se especifica en cargar datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
En los ejemplos de este tema se usan using las siguientes / Imports instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, consulte Cómo Cree un proyecto de LINQ to DataSet en VisualStudio.
Distinct
Ejemplo
Este ejemplo usa el método Distinct para quitar elementos duplicados de una secuencia.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
// Create duplicate rows by adding the same 100 rows to the list.
foreach (DataRow row in contactsTableWith100Rows.Rows)
rows.Add(row);
DataTable table =
System.Data.DataTableExtensions.CopyToDataTable<DataRow>(rows);
Console.WriteLine("Unique contacts:");
foreach (DataRow uniqueContact in uniqueContacts)
{
Console.WriteLine(uniqueContact.Field<Int32>("ContactID"));
}
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)
' Create duplicate rows by adding the same 100 rows to the list.
For Each row In contactsTableWith100Rows.Rows
rows.Add(row)
Next
Dim table = _
System.Data.DataTableExtensions.CopyToDataTable(Of DataRow)(rows)
Console.WriteLine("Unique contacts:")
For Each uniqueContact In uniqueContacts
Console.WriteLine(uniqueContact.Field(Of Integer)("ContactID"))
Next
Except
Ejemplo
Este ejemplo usa el método Except para devolver contactos que aparecen en la primera tabla pero no en la
segunda.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
Dim query1 = _
From contact In contactTable.AsEnumerable() _
Where contact.Field(Of String)("Title") = "Ms." _
Select contact
Dim query2 = _
From contact In contactTable.AsEnumerable() _
Where contact.Field(Of String)("FirstName") = "Sandra" _
Select contact
Dim query1 = _
From contact In contactTable.AsEnumerable() _
Where contact.Field(Of String)("Title") = "Ms." _
Select contact
Dim query2 = _
From contact In contactTable.AsEnumerable() _
Where contact.Field(Of String)("FirstName") = "Sandra" _
Select contact
Unión
Ejemplo
Este ejemplo usa el método Union para devolver contactos únicos de cualquiera de las dos tablas.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
Dim query1 = _
From contact In contactTable.AsEnumerable() _
Where contact.Field(Of String)("Title") = "Ms." _
Select contact
Dim query2 = _
From contact In contactTable.AsEnumerable() _
Where contact.Field(Of String)("FirstName") = "Sandra" _
Select contact
Vea también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Standard Query Operators Overview (C#) (Información general sobre operadores de consulta estándar (C#))
Información general sobre operadores de consulta estándar (Visual Basic)
Ejemplos de sintaxis de consulta basada en métodos:
Operadores de conversión (LINQ to DataSet)
23/10/2019 • 3 minutes to read • Edit Online
Los ejemplos de este tema muestran cómo usar los métodos ToArray, ToDictionary y ToList para ejecutar
inmediatamente una expresión de consulta.
El FillDataSet método utilizado en estos ejemplos se especifica en cargar datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
En los ejemplos de este tema se usan using las siguientes / Imports instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, vea Cómo: Cree un proyecto de LINQ to DataSet en VisualStudio.
ToArray
Ejemplo
En este ejemplo se utiliza el método ToArray para evaluar de forma inmediata una secuencia en una matriz.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
IEnumerable<DataRow> query =
from product in productsArray
orderby product.Field<Decimal>("ListPrice") descending
select product;
Dim query = _
From product In productsArray _
Select product _
Order By product.Field(Of Decimal)("ListPrice") Descending
ToDictionary
Ejemplo
En este ejemplo se utiliza el método ToDictionary para evaluar de forma inmediata una secuencia y una expresión
de clave relacionada en un diccionario.
ToList
Ejemplo
En este ejemplo se utiliza el método ToList para evaluar inmediatamente una secuencia en List<T>, donde T es de
tipo DataRow.
IEnumerable<DataRow> query =
from product in productList
orderby product.Field<string>("Name")
select product;
Dim query = _
From product In productList _
Select product _
Order By product.Field(Of String)("Name")
Los ejemplos de este tema muestran cómo usar los métodos First y ElementAt para obtener elementos DataRow
de un DataSet usando la sintaxis de expresiones de consulta.
El FillDataSet método utilizado en estos ejemplos se especifica en Carga de datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
Los ejemplos de este using / Imports tema utilizan las siguientes instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, vea Cómo: crear un proyecto LINQ to DataSet en Visual Studio.
ElementAt
Ejemplo
Este ejemplo usa el método ElementAt para recuperar la quinta dirección donde PostalCode == "M4B 1V7".
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var fifthAddress = (
from address in addresses.AsEnumerable()
where address.Field<string>("PostalCode") == "M4B 1V7"
select address.Field<string>("AddressLine1"))
.ElementAt(5);
Dim fifthAddress = ( _
From address In addresses.AsEnumerable() _
Where address.Field(Of String)("PostalCode") = "M4B 1V7" _
Select address.Field(Of String)("AddressLine1")).ElementAt(5)
Primero
Ejemplo
Este ejemplo usar el método First para devolver el primer contacto cuyo nombre es 'Brooke'.
DataRow query = (
from contact in contacts.AsEnumerable()
where (string)contact["FirstName"] == "Brooke"
select contact)
.First();
Dim query = ( _
From contact In contacts.AsEnumerable() _
Where contact.Field(Of String)("FirstName") = "Brooke" _
Select contact).First()
Consulte también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Información general sobre operadores de consulta estándar (C#)
Información general sobre operadores de consulta estándar (Visual Basic)
Ejemplos de sintaxis de consulta basada en métodos:
Operadores de agregado (LINQ to DataSet)
23/10/2019 • 15 minutes to read • Edit Online
Los ejemplos de este tema muestran cómo utilizar los operadores Aggregate, Average, Count, LongCount, Max,
Min y Sum para consultar DataSet y agregar datos utilizando sintaxis de consulta basada en métodos.
El FillDataSet método utilizado en estos ejemplos se especifica en cargar datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
En los ejemplos de este tema se usan using las siguientes / Imports instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, consulte Cómo Cree un proyecto de LINQ to DataSet en VisualStudio.
Agregar
Ejemplo
En este ejemplo se utiliza el método Aggregate para obtener los cinco primeros contactos de la tabla Contact y
compilar una lista de apellidos delimitada por comas.
string nameList =
contacts.Take(5).Select(contact => contact.Field<string>("LastName")).Aggregate((workingList, next) =>
workingList + "," + next);
Console.WriteLine(nameList);
' Fill the DataSet.
Dim ds As New DataSet()
ds.Locale = CultureInfo.InvariantCulture
' See the FillDataSet method in the Loading Data Into a DataSet topic.
FillDataSet(ds)
Console.WriteLine(nameList)
Average
Ejemplo
En este ejemplo se utiliza el método Average para encontrar el precio de venta promedio de los productos.
Decimal averageListPrice =
products.Average(product => product.Field<Decimal>("ListPrice"));
Ejemplo
En este ejemplo se utiliza el método Average para encontrar el precio de venta promedio de cada estilo de
productos.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
Dim query = _
From product In products _
Group product By style = product.Field(Of String)("Style") Into g = Group _
Select New With _
{ _
.Style = style, _
.AverageListPrice = g.Average(Function(product) _
product.Field(Of Decimal)("ListPrice")) _
}
Ejemplo
En este ejemplo se utiliza el método Average para encontrar el importe total a pagar promedio.
Ejemplo
En este ejemplo se utiliza el método Average para obtener el importe total a pagar promedio de cada id. de
contacto.
var query =
from order in orders.AsEnumerable()
group order by order.Field<Int32>("ContactID") into g
select new
{
Category = g.Key,
averageTotalDue =
g.Average(order => order.Field<decimal>("TotalDue"))
};
Dim query = _
From order In orders.AsEnumerable() _
Group order By contactID = order.Field(Of Int32)("ContactID") Into g = Group _
Select New With _
{ _
.Category = contactID, _
.averageTotalDue = g.Average(Function(order) order. _
Field(Of Decimal)("TotalDue")) _
}
Ejemplo
En este ejemplo se utiliza el método Average para obtener los pedidos con el TotalDue promedio de cada
contacto.
var query =
from order in orders.AsEnumerable()
group order by order.Field<Int32>("ContactID") into g
let averageTotalDue = g.Average(order => order.Field<decimal>("TotalDue"))
select new
{
Category = g.Key,
CheapestProducts =
g.Where(order => order.Field<decimal>("TotalDue") ==
averageTotalDue)
};
Dim query = _
From order In orders.AsEnumerable() _
Group order By contactID = order.Field(Of Int32)("ContactID") Into g = Group _
Let averageTotalDue = g.Average(Function(order) order.Field(Of Decimal)("TotalDue")) _
Select New With _
{ _
.Category = contactID, _
.CheapestProducts = g.Where(Function(order) order. _
Field(Of Decimal)("TotalDue") = averageTotalDue) _
}
Número
Ejemplo
En este ejemplo se utiliza el método Count para devolver el número de productos de la tabla Product .
Ejemplo
En este ejemplo se utiliza el método Count para devolver una lista de id. de contactos y el número de pedidos que
tiene cada uno de ellos.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
Dim query = _
From contact In contacts.AsEnumerable() _
Select New With _
{ _
.ContactID = contact.Field(Of Integer)("ContactID"), _
.OrderCount = contact.GetChildRows("SalesOrderContact").Count() _
}
Ejemplo
En este ejemplo se agrupan los productos por colores y se utiliza el método Count para devolver el número de
productos de cada grupo de color.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from product in products.AsEnumerable()
group product by product.Field<string>("Color") into g
select new { Color = g.Key, ProductCount = g.Count() };
Dim query = _
From product In products.AsEnumerable() _
Group product By color = product.Field(Of String)("Color") Into g = Group _
Select New With {.Color = color, .ProductCount = g.Count()}
LongCount
Ejemplo
En este ejemplo se obtiene el recuento de contactos como un entero largo.
Máx.
Ejemplo
En este ejemplo se utiliza el método Max para obtener el mayor importe total a pagar.
Ejemplo
En este ejemplo se utiliza el método Max para obtener el mayor importe total a pagar de cada id. de contacto.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from order in orders.AsEnumerable()
group order by order.Field<Int32>("ContactID") into g
select new
{
Category = g.Key,
maxTotalDue =
g.Max(order => order.Field<decimal>("TotalDue"))
};
Dim query = _
From order In orders.AsEnumerable() _
Group order By contactID = order.Field(Of Int32)("ContactID") Into g = Group _
Select New With _
{ _
.Category = contactID, _
.maxTotalDue = _
g.Max(Function(order) order.Field(Of Decimal)("TotalDue")) _
}
For Each order In query
Console.WriteLine("ContactID = {0} " & vbTab & _
" Maximum TotalDue = {1}", _
order.Category, order.maxTotalDue)
Next
Ejemplo
En este ejemplo se utiliza el método Max para obtener los pedidos con el TotalDue mayor de cada id. contacto.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from order in orders.AsEnumerable()
group order by order.Field<Int32>("ContactID") into g
let maxTotalDue = g.Max(order => order.Field<decimal>("TotalDue"))
select new
{
Category = g.Key,
CheapestProducts =
g.Where(order => order.Field<decimal>("TotalDue") ==
maxTotalDue)
};
Dim query = _
From order In orders.AsEnumerable() _
Group order By contactID = order.Field(Of Int32)("ContactID") Into g = Group _
Let maxTotalDue = g.Max(Function(order) order.Field(Of Decimal)("TotalDue")) _
Select New With _
{ _
.Category = contactID, _
.CheapestProducts = _
g.Where(Function(order) order. _
Field(Of Decimal)("TotalDue") = maxTotalDue) _
}
Mín.
Ejemplo
En este ejemplo se utiliza el método Min para obtener el menor importe total a pagar.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
Ejemplo
En este ejemplo se utiliza el método Min para obtener el menor importe total a pagar de cada id. de contacto.
var query =
from order in orders.AsEnumerable()
group order by order.Field<Int32>("ContactID") into g
select new
{
Category = g.Key,
smallestTotalDue =
g.Min(order => order.Field<decimal>("TotalDue"))
};
Dim query = _
From order In orders.AsEnumerable() _
Group order By contactID = order.Field(Of Int32)("ContactID") Into g = Group _
Select New With _
{ _
.Category = contactID, _
.smallestTotalDue = g.Min(Function(order) _
order.Field(Of Decimal)("TotalDue")) _
}
Ejemplo
En este ejemplo se utiliza el método Min para obtener el pedido con el menor importe total a pagar de cada
contacto.
var query =
from order in orders.AsEnumerable()
group order by order.Field<Int32>("ContactID") into g
let minTotalDue = g.Min(order => order.Field<decimal>("TotalDue"))
select new
{
Category = g.Key,
smallestTotalDue =
g.Where(order => order.Field<decimal>("TotalDue") ==
minTotalDue)
};
Dim query = _
From order In orders.AsEnumerable() _
Group order By contactID = order.Field(Of Int32)("ContactID") Into g = Group _
Let minTotalDue = g.Min(Function(order) order.Field(Of Decimal)("TotalDue")) _
Select New With _
{ _
.Category = contactID, _
.smallestTotalDue = g.Where(Function(order) order. _
Field(Of Decimal)("TotalDue") = minTotalDue) _
}
Sum
Ejemplo
En este ejemplo se utiliza el método Sum para obtener el número total de cantidades de pedido de la tabla
SalesOrderDetail .
Ejemplo
En este ejemplo se utiliza el método Sum para obtener el importe total a pagar de cada id. de contacto.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
from order in orders.AsEnumerable()
group order by order.Field<Int32>("ContactID") into g
select new
{
Category = g.Key,
TotalDue = g.Sum(order => order.Field<decimal>("TotalDue")),
};
foreach (var order in query)
{
Console.WriteLine("ContactID = {0} \t TotalDue sum = {1}",
order.Category, order.TotalDue);
}
Dim query = _
From order In orders.AsEnumerable() _
Group order By contactID = order.Field(Of Int32)("ContactID") Into g = Group _
Select New With _
{ _
.Category = contactID, _
.TotalDue = g.Sum(Function(order) order. _
Field(Of Decimal)("TotalDue")) _
}
Vea también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Standard Query Operators Overview (C#) (Información general sobre operadores de consulta estándar (C#))
Información general sobre operadores de consulta estándar (Visual Basic)
Ejemplos de sintaxis de consulta basada en métodos:
Join (LINQ to DataSet)
23/10/2019 • 4 minutes to read • Edit Online
La combinación es una operación importante de las consultas dirigidas a orígenes de datos que no tienen
relaciones navegables entre ellos, como las tablas de bases de datos relacionales. Una combinación de dos
orígenes de datos es la asociación de objetos en un origen de datos con objetos que comparten un atributo común
en el otro origen de datos. Para obtener más información, vea información general sobre operadoresC#de consulta
estándar () o información general sobre operadores de consulta estándar (Visual Basic).
Los ejemplos de este tema muestran cómo usar el métodoJoin para consultar DataSet usando la sintaxis de
consulta basada en métodos.
El FillDataSet método utilizado en estos ejemplos se especifica en cargar datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
En los ejemplos de este tema se usan using las siguientes / Imports instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, consulte Cómo Cree un proyecto de LINQ to DataSet en VisualStudio.
Unir
Ejemplo
En este ejemplo se realiza una combinación en las tablas Contact y SalesOrderHeader .
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
var query =
contacts.AsEnumerable().Join(orders.AsEnumerable(),
order => order.Field<Int32>("ContactID"),
contact => contact.Field<Int32>("ContactID"),
(contact, order) => new
{
ContactID = contact.Field<Int32>("ContactID"),
SalesOrderID = order.Field<Int32>("SalesOrderID"),
FirstName = contact.Field<string>("FirstName"),
Lastname = contact.Field<string>("Lastname"),
TotalDue = order.Field<decimal>("TotalDue")
});
Dim query = _
contacts.AsEnumerable().Join(orders.AsEnumerable(), _
Function(order) order.Field(Of Int32)("ContactID"), _
Function(contact) contact.Field(Of Int32)("ContactID"), _
Function(contact, order) New With _
{ _
.ContactID = contact.Field(Of Int32)("ContactID"), _
.SalesOrderID = order.Field(Of Int32)("SalesOrderID"), _
.FirstName = contact.Field(Of String)("FirstName"), _
.Lastname = contact.Field(Of String)("Lastname"), _
.TotalDue = order.Field(Of Decimal)("TotalDue") _
})
Ejemplo
En este ejemplo se realiza una combinación en las tablas Contact y SalesOrderHeader , agrupando los resultados
por id. de contacto.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
Dim query = _
contacts.AsEnumerable().Join(orders.AsEnumerable(), _
Function(order) order.Field(Of Int32)("ContactID"), _
Function(contact) contact.Field(Of Int32)("ContactID"), _
Function(contact, order) New With _
{ _
.ContactID = contact.Field(Of Int32)("ContactID"), _
.SalesOrderID = order.Field(Of Int32)("SalesOrderID"), _
.FirstName = contact.Field(Of String)("FirstName"), _
.Lastname = contact.Field(Of String)("Lastname"), _
.TotalDue = order.Field(Of Decimal)("TotalDue") _
}) _
.GroupBy(Function(record) record.ContactID)
Vea también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Standard Query Operators Overview (C#) (Información general sobre operadores de consulta estándar (C#))
Información general sobre operadores de consulta estándar (Visual Basic)
Ejemplos de combinación
Ejemplos de conjuntos de DataSet
Ejemplos de operadores específicos de conjuntos de
datos (LINQ to DataSet)
23/10/2019 • 2 minutes to read • Edit Online
Los ejemplos de este tema muestran cómo usar los métodos CopyToDataTable y la clase DataRowComparer.
El FillDataSet método utilizado en estos ejemplos se especifica en cargar datos en un conjunto de datos.
Los ejemplos de este tema utilizan las tablas Contact, Address, Product, SalesOrderHeader y SalesOrderDetail en la
base de datos de ejemplo de AdventureWorks.
En los ejemplos de este tema se usan using las siguientes / Imports instrucciones:
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Globalization;
Option Explicit On
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.SqlClient
Imports System.Data.Common
Imports System.Globalization
Para obtener más información, consulte Cómo Cree un proyecto de LINQ to DataSet en VisualStudio.
CopyToDataTable
Ejemplo
En este ejemplo se carga un DataTable con resultados de consulta utilizando el método CopyToDataTable.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
IEnumerable<DataRow> query =
from contact in contacts1.AsEnumerable()
where contact.Field<string>("Title") == "Ms."
&& contact.Field<string>("FirstName") == "Carla"
select contact;
Dim query = _
From contact In contactTable.AsEnumerable() _
Where contact.Field(Of String)("Title") = "Ms." _
And contact.Field(Of String)("FirstName") = "Carla" _
Select contact
DataRowComparer
Ejemplo
En este ejemplo se comparan dos filas distintas de datos utilizando DataRowComparer.
// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
Vea también
Carga de datos en un conjunto de datos
Ejemplos de LINQ to DataSet
Entity Data Model
08/11/2019 • 5 minutes to read • Edit Online
Entity Data Model (EDM) es un conjunto de conceptos que describen la estructura de los datos,
independientemente del formato en el que estén almacenados. EDM se basa en el modelo entidad-relación
(Entity-Relationship Model) descrito por Peter Chen en 1976, pero también incorpora nuevas funciones y amplía
sus usos tradicionales.
EDM soluciona los desafíos que plantea el tener datos almacenados en muchos formatos. Considere, por
ejemplo, un negocio que almacena los datos en bases de datos relacionales, archivos de texto, archivos XML,
hojas de cálculo e informes. Esto presenta importantes desafíos en el modelado de datos, el diseño de
aplicaciones y el acceso a los datos. Al diseñar una aplicación orientada a datos, el desafío consiste en escribir un
código eficaz y que se pueda mantener sin sacrificar la eficacia del acceso a los datos, el almacenamiento y la
escalabilidad. Cuando los datos tienen una estructura relacional, el acceso a los datos, el almacenamiento y la
escalabilidad resultan muy eficaces, pero es más difícil escribir un código eficaz y que se pueda mantener.
Cuando los datos tienen una estructura de objeto, se invierten las ventajas; es decir, la escritura de un código
eficaz y que se pueda mantener se consigue a costa de la eficacia en el acceso a los datos, el almacenamiento y la
escalabilidad. Aunque es posible encontrar el equilibrio adecuado entre ambos métodos, surgen nuevos desafíos
cuando se mueven los datos de un formato a otro. Entity Data Model resuelve estos desafíos describiendo la
estructura de los datos en forma de entidades y relaciones que son independientes de cualquier esquema de
almacenamiento. Esto hace que el formato en el que están almacenados los datos sea irrelevante a la hora de
diseñar y desarrollar las aplicaciones. Y, dado que las entidades y las relaciones describen la estructura de los
datos tal como se usan en una aplicación (no el formato en el que están almacenados), pueden evolucionar al
mismo tiempo que la aplicación.
Un modelo conceptual ( conceptual model ) es una representación específica de la estructura de los datos en
forma de entidades y relaciones, y normalmente se define mediante un lenguaje específico de dominio (DSL)
que implementa los conceptos de EDM. El lenguaje de definición de esquemas conceptuales (CSDL) es un
ejemplo de este tipo de lenguaje específico de dominio. Las entidades y relaciones descritas en un modelo
conceptual se pueden considerar como abstracciones de objetos y asociaciones en una aplicación. Esto permite a
los desarrolladores centrarse en el modelo conceptual sin tener que preocuparse por el esquema de
almacenamiento, así como escribir el código teniendo en cuenta la eficacia y el mantenimiento. Mientras tanto,
los diseñadores del esquema de almacenamiento pueden centrarse en la eficacia en el acceso a los datos, el
almacenamiento y la escalabilidad.
En esta sección
Los temas de esta sección describen los conceptos de Entity Data Model. Cualquier ADSL que implemente EDM
debe incluir los conceptos descritos a continuación. Tenga en cuenta que el Entity Framework ADO.net utiliza
CSDL para definir los modelos conceptuales. Para obtener más información, consulta CSDL Specification.
Conceptos clave de Entity Data Model
Entity Data Model: Espacios de nombres
Entity Data Model: Tipos de datos primitivos
Entity Data Model: Herencia
extremo de asociación
multiplicidad de extremo de asociación
conjunto de asociaciones
extremo del conjunto de asociaciones
tipo de asociación
tipo complejo
contenedor de entidades
clave de entidad
conjunto de entidades
tipo de entidad
facet
propiedad de clave externa
función declarada por el modelo
función definida por el modelo
propiedad de navegación
propiedad
restricción de integridad referencial
Vea también
ADO.NET Entity Data Model herramientas
Información general sobre el archivo. edmx
Especificación CSDL
Conceptos clave de Entity Data Model
08/11/2019 • 7 minutes to read • Edit Online
El Entity Data Model (EDM) usa tres conceptos clave para describir la estructura de los datos: el tipo de entidad,
el tipo de asociacióny la propiedad. Estos son los conceptos más importantes para describir la estructura de
datos en cualquier implementación de EDM.
Tipo de entidad
El tipo de entidad es el bloque de creación fundamental para describir la estructura de los datos con el Entity
Data Model. En un modelo conceptual, los tipos de entidad se construyen a partir de propiedades y describen la
estructura de conceptos de nivel superior, como clientes y pedidos en una aplicación empresarial. Del mismo
modo que una definición de clase en un programa es una plantilla para las instancias de la clase, un tipo de
entidad es una plantilla para las entidades. Una entidad representa un objeto concreto (como un cliente o pedido
concreto). Cada entidad debe tener una clave de entidad única dentro de un conjunto de entidades. Un conjunto
de entidades es una colección de instancias de un tipo de entidad concreto. Los conjuntos de entidades (y los
conjuntos de asociaciones) se agrupan de forma lógica en un contenedor de entidades.
Los tipos de entidad admiten la herencia: es decir, un tipo de entidad se puede derivar de otro. Para obtener más
información, vea Entity Data Model: herencia.
Tipo de asociación
Un tipo de asociación (también denominado Asociación) es el bloque de creación fundamental para describir las
relaciones en el Entity Data Model. En un modelo conceptual, una asociación representa una relación entre dos
tipos de entidad (como Customer y Order). Cada asociación tiene dos extremos de asociación que especifican los
tipos de entidad implicados en la asociación. Cada extremo de la asociación también especifica una multiplicidad
de extremo de asociación que indica el número de entidades que pueden estar en ese extremo de la asociación.
Una multiplicidad de extremo de asociación puede tener un valor de uno (1), cero o uno (0.. 1) o varios (*). Se
puede tener acceso a las entidades de un extremo de una asociación a través de las propiedades de navegacióno
a través de claves externas si se exponen en un tipo de entidad. Para obtener más información, consulte Foreign
Key Property.
En una aplicación, una instancia de una asociación representa una asociación concreta (como por ejemplo una
asociación entre una instancia Customer y una instancia Order). Las instancias de asociación se agrupan
lógicamente en un conjunto de asociaciones. Los conjuntos de asociaciones (y los conjuntos de entidades) se
agrupan de forma lógica en un contenedor de entidades.
Propiedad.
Los tipos de entidad contienen propiedades que definen su estructura y sus características. Por ejemplo, un tipo
de entidad Customer puede tener propiedades como CustomerId, Name y Address.
Las propiedades en un modelo conceptual son análogas a las propiedades definidas en una clase en un
programa. Del mismo modo que las propiedades en una clase definen la forma de la clase y proporcionan
información sobre los objetos, las propiedades en un modelo conceptual definen la forma de un tipo de entidad
y proporcionan información sobre las instancias del tipo de entidad.
Una propiedad puede contener datos primitivos (como una cadena, un entero o un valor booleano) o estructura
los datos (como un tipo complejo). Para obtener más información, vea Entity Data Model: tipos de datos
primitivos.
Representaciones de un modelo conceptual
Un modelo conceptual es una representación específica de la estructura de algunos datos como entidades y
relaciones. Una manera de representar un modelo conceptual es con un diagrama. El siguiente diagrama
representa un modelo conceptual con tres tipos de entidad ( Book , Publisher y Author ) y dos asociaciones (
PublishedBy y WrittenBy ):
Esta representación, sin embargo, tiene algunas limitaciones a la hora de representar algunos detalles acerca del
modelo. Por ejemplo, la información sobre el tipo de propiedad y el conjunto de entidades no se representa en el
diagrama. La riqueza de un modelo conceptual se puede representar con mayor claridad mediante un lenguaje
específico de dominio (ADSL). El Entity Framework ADO.net usa un DSL basado en XML denominado lenguaje de
definición de esquemas conceptuales (CSDL) para definir los modelos conceptuales. A continuación se muestra
la definición CSDL del modelo conceptual del diagrama anterior:
<Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm"
xmlns:cg="http://schemas.microsoft.com/ado/2006/04/codegeneration"
xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"
Namespace="BooksModel" Alias="Self">
<EntityContainer Name="BooksContainer" >
<EntitySet Name="Books" EntityType="BooksModel.Book" />
<EntitySet Name="Publishers" EntityType="BooksModel.Publisher" />
<EntitySet Name="Authors" EntityType="BooksModel.Author" />
<AssociationSet Name="PublishedBy" Association="BooksModel.PublishedBy">
<End Role="Book" EntitySet="Books" />
<End Role="Publisher" EntitySet="Publishers" />
</AssociationSet>
<AssociationSet Name="WrittenBy" Association="BooksModel.WrittenBy">
<End Role="Book" EntitySet="Books" />
<End Role="Author" EntitySet="Authors" />
</AssociationSet>
</EntityContainer>
<EntityType Name="Book">
<Key>
<PropertyRef Name="ISBN" />
</Key>
<Property Type="String" Name="ISBN" Nullable="false" />
<Property Type="String" Name="Title" Nullable="false" />
<Property Type="Decimal" Name="Revision" Nullable="false" Precision="29" Scale="29" />
<NavigationProperty Name="Publisher" Relationship="BooksModel.PublishedBy"
FromRole="Book" ToRole="Publisher" />
<NavigationProperty Name="Authors" Relationship="BooksModel.WrittenBy"
FromRole="Book" ToRole="Author" />
</EntityType>
<EntityType Name="Publisher">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Type="Int32" Name="Id" Nullable="false" />
<Property Type="String" Name="Name" Nullable="false" />
<Property Type="String" Name="Address" Nullable="false" />
<NavigationProperty Name="Books" Relationship="BooksModel.PublishedBy"
FromRole="Publisher" ToRole="Book" />
</EntityType>
<EntityType Name="Author">
<Key>
<PropertyRef Name="Name" />
<PropertyRef Name="Address" />
</Key>
<Property Type="String" Name="Name" Nullable="false" />
<Property Type="String" Name="Address" Nullable="false" />
<NavigationProperty Name="Books" Relationship="BooksModel.WrittenBy"
FromRole="Author" ToRole="Book" />
</EntityType>
<Association Name="PublishedBy">
<End Type="BooksModel.Book" Role="Book" Multiplicity="*" />
<End Type="BooksModel.Publisher" Role="Publisher" Multiplicity="1" />
</Association>
<Association Name="WrittenBy">
<End Type="BooksModel.Book" Role="Book" Multiplicity="*" />
<End Type="BooksModel.Author" Role="Author" Multiplicity="*" />
</Association>
</Schema>
Vea también
Entity Data Model
Entity Data Model: Espacios de nombres
08/11/2019 • 2 minutes to read • Edit Online
Un espacio de nombres en el Entity Data Model (EDM) es un contenedor abstracto para tipos de entidad, tipos
complejosy asociaciones. Los espacios de nombres en EDM son similares a los de un lenguaje de programación:
proporcionan el contexto para los objetos que contienen, así como una manera de eliminar la ambigüedad de
objetos que tienen el mismo nombre (pero que contienen espacios de nombres diferentes).
Ejemplo
El Entity Framework ADO.net usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición de
esquemas conceptuales (CSDL) para definir los modelos conceptuales. En el siguiente código CSDL se utiliza un
espacio de nombres para identificar un tipo que se define en un modelo conceptual diferente. En el ejemplo se
define un tipo de entidad ( Publisher ) con una propiedad de tipo complejo ( Address ) que se importa del espacio
de nombres ExtendedBooksModel . Observe que el elemento Using indica que se ha importado un espacio de
nombres. Observe también que el tipo de la propiedad Address se define utilizando su nombre completo (
ExtendedBooksModel.Address ), lo que indica que este tipo se define en el espacio de nombres ExtendedBooksModel .
<Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm"
xmlns:cg="http://schemas.microsoft.com/ado/2006/04/codegeneration"
xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"
Namespace="BooksModel" Alias="Self">
<EntityType Name="Publisher">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Type="Int32" Name="Id" Nullable="false" />
<Property Type="String" Name="Name" Nullable="false" />
<Property Type="BMExt.Address" Name="Address" Nullable="false" />
</EntityType>
</Schema>
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
Entity Data Model: tipos de datos primitivos
23/10/2019 • 3 minutes to read • Edit Online
El Entity Data Model (EDM) admite un conjunto de tipos de datos primitivos abstractos (como String, Boolean,
Int32, etc.) que se usan para definir propiedades en un modelo conceptual. Estos tipos de datos primitivos son
representantes de los tipos de datos primitivos reales compatibles con el entorno de almacenamiento o de
hospedaje, como una base de datos de SQL Server o Common Language Runtime (CLR). EDM no define la
semántica de las operaciones o conversiones sobre los tipos de datos primitivos; es el propio entorno de
almacenamiento o de hospedaje el que lo hace. Normalmente, los tipos de datos primitivos de EDM se asignan a
los tipos de datos primitivos correspondientes del entorno de almacenamiento o de hospedaje. Para obtener
información sobre cómo asigna el Entity Framework tipos primitivos en el EDM a SQL Server tipos de datos, vea
SqlClient para Entity Framework.
NOTE
EDM no admite colecciones de tipos de datos primitivos.
Para obtener información sobre los tipos de datos estructurados en el EDM, vea tipo de entidad y tipo complejo.
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
Entity Data Model: Herencia
08/11/2019 • 3 minutes to read • Edit Online
El Entity Data Model (EDM) admite la herencia para los tipos de entidad. La herencia en EDM es similar a la
herencia para las clases en los lenguajes de programación orientados a objetos. Al igual que sucede con las clases
de los lenguajes orientados a objetos, en un modelo conceptual se puede definir un tipo de entidad (un tipo
derivado) que herede de otro tipo de entidad (el tipo base). Sin embargo, a diferencia de las clases de la
programación orientada a objetos, en un modelo conceptual, el tipo derivado hereda siempre todas las
propiedades y propiedades de navegación del tipo base. No se pueden reemplazar las propiedades heredadas en
un tipo derivado.
En un modelo conceptual, se pueden crear jerarquías de herencia en las que un tipo derivado hereda de otro tipo
derivado. El tipo situado en la parte superior de la jerarquía (el tipo de la jerarquía que no es un tipo derivado) se
denomina tipo raíz. En una jerarquía de herencia, la clave de entidad debe definirse en el tipo raíz.
No se pueden crear jerarquías de herencia en las que un tipo derivado hereda de más de un tipo. Por ejemplo, en
un modelo conceptual con un tipo de entidad Book , se podrían definir tipos derivados FictionBook y
NonFictionBook que hereden de Book . Sin embargo, no se podría definir un tipo que herede de los tipos
FictionBook y NonFictionBook .
Ejemplo
En el diagrama siguiente se muestra un modelo conceptual con cuatro tipos de entidad: Book , FictionBook ,
Publisher y Author . El tipo de entidad FictionBook es un tipo derivado, que hereda del tipo de entidad Book . El
tipo FictionBook hereda las propiedades ISBN (Key) , Title y Revision , y define una propiedad adicional
denominada Genre .
El Entity Framework ADO.net usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición de
esquemas conceptuales (CSDL) para definir los modelos conceptuales. El código CSDL siguiente define un tipo de
entidad, FictionBook , que hereda del tipo Book (como en el diagrama anterior):
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
extremo de asociación
08/11/2019 • 3 minutes to read • Edit Online
Un extremo de asociación identifica el tipo de entidad en un extremo de una Asociación y el número de instancias
de tipo de entidad que pueden existir en ese extremo de una asociación. Los extremos de asociación se definen
como parte de una asociación, y esta debe tener exactamente dos extremos. Las propiedades de navegación
permiten la navegación de un extremo de asociación al otro.
Una definición de extremo de asociación contiene la información siguiente:
Uno de los tipos de entidad implicados en la asociación. (Necesario)
NOTE
En una asociación determinada, el tipo de entidad especificado para cada extremo de la asociación puede ser el
mismo. Esto crea una auto-asociación.
Una multiplicidad de extremo de asociación que indica el número de instancias de tipo de entidad que
pueden estar en un extremo de la asociación. Una multiplicidad de extremo de asociación puede tener un
valor de uno (1), cero o uno (0.. 1) o varios (*).
Nombre para el extremo de la asociación. (Opcional)
Información sobre las operaciones que se realizan en el extremo de la asociación, como por ejemplo la
eliminación en cascada. (Opcional)
Ejemplo
El diagrama siguiente muestra un modelo conceptual con dos asociaciones: PublishedBy y WrittenBy . Los
extremos de asociación para la asociación PublishedBy son los tipos de entidad Book y Publisher . La
multiplicidad del extremo de Publisher es uno (1) y la multiplicidad del extremo de Book es muchos (*), lo que
indica que un publicador publica muchos libros y un libro publicado por un publicador.
El Entity Framework ADO.NET usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición de
esquemas conceptuales (CSDL) para definir los modelos conceptuales. El CSDL siguiente define la asociación
PublishedBy mostrada en el diagrama anterior. Tenga en cuenta que el tipo, el nombre y la multiplicidad de cada
extremo de la asociación se especifican mediante atributos XML (los atributos Type , Role y Multiplicity ,
respectivamente). La información adicional sobre las operaciones realizadas en un extremo se especifica
mediante un elemento XML (el elemento OnDelete -). En este caso, si se elimina un editor, también se eliminan
todos los libros asociados.
<Association Name="PublishedBy">
<End Type="BooksModel.Book" Role="Book" Multiplicity="*" />
<End Type="BooksModel.Publisher" Role="Publisher" Multiplicity="1" >
<OnDelete Action="Cascade" />
</End>
</Association>
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
multiplicidad de extremo de asociación
08/11/2019 • 2 minutes to read • Edit Online
La multiplicidad de extremo de asociación define el número de instancias de tipo de entidad que pueden estar en
un extremo de una Asociación.
Una multiplicidad de extremo de asociación puede tener uno de los valores siguientes:
uno (1): indica que existe exactamente una instancia de tipo de entidad en el extremo de la asociación.
cero o uno (0..1): indica que pueden existir cero o una instancia de tipo de entidad en el extremo de la
asociación.
Many (*): indica que no existe ninguna instancia de tipo de entidad, o más, en el extremo de la asociación.
Normalmente, una asociación se caracteriza por sus multiplicidades de extremo de asociación. Por ejemplo, si los
extremos de una asociación tienen multiplicidades uno (1) y muchos (*), la asociación se denomina una
asociación uno a varios. En el ejemplo siguiente, la asociación PublishedBy es una asociación uno a varios (un
publicador publica muchos libros y un libro solo puede ser publicado por un publicador). La asociación
WrittenBy es una asociación varios a varios (un libro puede tener varios autores y un autor puede escribir varios
libros).
Ejemplo
El diagrama siguiente muestra un modelo conceptual con dos asociaciones: PublishedBy y WrittenBy . Los
extremos de asociación para la asociación PublishedBy son los tipos de entidad Book y Publisher . La
multiplicidad del extremo Publisher es uno (1) y la multiplicidad del extremo Book es muchos (*).
El Entity Framework ADO.NET usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición de
esquemas conceptuales (CSDL) para definir los modelos conceptuales. El código CSDL siguiente define la
asociación PublishedBy mostrada en el diagrama anterior:
<Association Name="PublishedBy">
<End Type="BooksModel.Book" Role="Book" Multiplicity="*" />
<End Type="BooksModel.Publisher" Role="Publisher" Multiplicity="1" />
</Association>
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
conjunto de asociaciones
08/11/2019 • 4 minutes to read • Edit Online
Un conjunto de asociaciones es un contenedor lógico para las instancias de Asociación del mismo tipo. Un
conjunto de asociaciones no es una construcción del modelado de datos; es decir, no describe la estructura de
datos o relaciones. En su lugar, un conjunto de asociaciones proporciona una construcción para que un entorno
de hospedaje o de almacenamiento (como Common Language Runtime o una base de datos de SQL Server)
agrupe las instancias de asociaciones a fin de que se puedan asignar a un almacén de datos.
Un conjunto de asociaciones se define dentro de un contenedor de entidades, que es una agrupación lógica de
conjuntos de entidades y conjuntos de asociaciones.
Una definición de un conjunto de asociaciones contiene la información siguiente:
El nombre del conjunto de asociaciones. (Necesario)
La asociación cuyas instancias contendrá. (Necesario)
Dos extremos del conjunto de asociaciones.
Ejemplo
El diagrama siguiente muestra un modelo conceptual con dos asociaciones: PublishedBy y WrittenBy . Aunque
la información sobre los conjuntos de asociaciones no se muestra en el diagrama, el diagrama siguiente muestra
un ejemplo de conjuntos de asociaciones y conjuntos de entidades basados en este modelo.
El siguiente ejemplo muestra un conjunto de asociaciones ( PublishedBy y dos conjuntos de entidades ( Books y
Publishers ) basados en el modelo conceptual mostrado anteriormente. BI en el conjunto de entidades Books
representa una instancia del tipo de entidad Book en tiempo de ejecución. De forma similar, PJ representa una
instancia de Publisher en el conjunto de entidades Publishers . BiPj representa una instancia de la Asociación
PublishedBy en el conjunto de asociaciones PublishedBy .
El Entity Framework ADO.net usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición de
esquemas conceptuales (CSDL) para definir los modelos conceptuales. El siguiente CSDL define un contenedor
de entidad con un conjunto de asociaciones para cada asociación en el diagrama anterior. Observe que el
nombre y asociación para cada conjunto de asociaciones se definen utilizando los atributos XML.
Es posible definir varios conjuntos de asociaciones por asociación, siempre y cuando no haya dos conjuntos de
asociaciones que compartan un extremo del conjunto de asociaciones. En el siguiente CSDL se define un
contenedor de entidades con dos conjuntos de asociaciones para la asociación WrittenBy . Observe que se han
definido varios conjuntos de entidades para los tipos de entidad Book y Author y que ningún conjunto de
asociaciones comparte un extremo del conjunto de asociaciones.
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
propiedad de clave externa
extremo del conjunto de asociaciones
08/11/2019 • 2 minutes to read • Edit Online
Un extremo del conjunto de asociaciones identifica el tipo de entidad y el conjunto de entidades al final de un
conjunto de asociaciones. Los extremos de conjuntos de asociaciones se definen como parte de un conjunto de
asociaciones, que debe tener exactamente dos extremos.
Una definición de extremo de conjunto de asociaciones contiene la información siguiente:
Uno de los tipos de entidad implicados en el conjunto de asociaciones. (Necesario)
El conjunto de entidades para el tipo de entidad implicado en el conjunto de asociaciones. (Necesario)
Ejemplo
El diagrama siguiente muestra un modelo conceptual con dos asociaciones: WrittenBy y PublishedBy .
El diagrama siguiente muestra un conjunto de asociaciones ( PublishedBy y dos conjuntos de entidades ( Books y
Publishers ) basados en el modelo conceptual mostrado anteriormente. Los extremos del conjunto de
asociaciones son los conjuntos de entidades Books y Publishers . BI en el conjunto de entidades Books
representa una instancia del tipo de entidad Book en tiempo de ejecución. De forma similar, PJ representa una
instancia de Publisher en el conjunto de entidades Publishers . BiPj representa una instancia de la Asociación
PublishedBy en el conjunto de asociaciones PublishedBy .
El Entity Framework ADO.net usa un DSL denominado lenguaje de definición de esquemas conceptuales (CSDL)
para definir los modelos conceptuales. El siguiente CSDL define un contenedor de entidad con un conjunto de
asociaciones para cada asociación en el diagrama anterior. Observe que los extremos del conjunto de asociaciones
se definen como parte de cada definición del conjunto de asociaciones.
<EntityContainer Name="BooksContainer" >
<EntitySet Name="Books" EntityType="BooksModel.Book" />
<EntitySet Name="Publishers" EntityType="BooksModel.Publisher" />
<EntitySet Name="Authors" EntityType="BooksModel.Author" />
<AssociationSet Name="PublishedBy" Association="BooksModel.PublishedBy">
<End Role="Book" EntitySet="Books" />
<End Role="Publisher" EntitySet="Publishers" />
</AssociationSet>
<AssociationSet Name="WrittenBy" Association="BooksModel.WrittenBy">
<End Role="Book" EntitySet="Books" />
<End Role="Author" EntitySet="Authors" />
</AssociationSet>
</EntityContainer>
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
tipo de asociación
08/11/2019 • 3 minutes to read • Edit Online
Un tipo de asociación (también denominado Asociación) es el bloque de creación fundamental para describir
las relaciones en el Entity Data Model (EDM). En un modelo conceptual, una asociación representa una relación
entre dos tipos de entidad (como Customer y Order ). En una aplicación, una instancia de una asociación
representa una asociación concreta (como por ejemplo una asociación entre una instancia de Customer y una
instancia de Order ). Las instancias de asociación se agrupan lógicamente en un conjunto de asociaciones.
Una definición de asociación contiene la siguiente información:
Un nombre único. (Necesario)
Dos extremosde la asociación, uno para cada tipo de entidad de la relación. (Necesario)
NOTE
Una asociación no puede representar una relación entre más de dos tipos de entidad. Sin embargo, una
asociación sí puede definir una auto-relación especificando el mismo tipo de entidad para cada uno de sus
extremos de asociación.
Ejemplo
El diagrama siguiente muestra un modelo conceptual con dos asociaciones: PublishedBy y WrittenBy . Los
extremos de asociación para la asociación PublishedBy son los tipos de entidad Book y Publisher . La
multiplicidad del extremo de Publisher es uno (1) y la multiplicidad del extremo de Book es muchos (*), lo
que indica que un publicador publica muchos libros y un libro publicado por un publicador.
El Entity Framework ADO.net usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición
de esquemas conceptuales (CSDL) para definir los modelos conceptuales. El código CSDL siguiente define la
asociación PublishedBy mostrada en el diagrama anterior:
<Association Name="PublishedBy">
<End Type="BooksModel.Book" Role="Book" Multiplicity="*" />
<End Type="BooksModel.Publisher" Role="Publisher" Multiplicity="1" />
</Association>
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
tipo complejo
08/11/2019 • 3 minutes to read • Edit Online
Un tipo complejo es una plantilla para definir propiedades enriquecidas y estructuradas en tipos de entidad o en
otros tipos complejos. Cada plantilla contiene lo siguiente:
Un nombre único. (Necesario)
NOTE
El nombre de un tipo complejo no puede coincidir con el nombre de un tipo de entidad dentro del mismo espacio
de nombres.
NOTE
Una propiedad de un tipo complejo puede ser otro tipo complejo.
Un tipo complejo es similar a un tipo de entidad, ya que un tipo complejo puede llevar una carga de datos en
forma de propiedades de tipo primitivo u otros tipos complejos. Sin embargo, existen algunas diferencias clave
entre los tipos complejos y los tipos de entidad:
Los tipos complejos no tienen identidades y, por consiguiente, no pueden existir de forma independiente.
Los tipos complejos solo pueden existir como propiedades en tipos de entidad u otros tipos complejos.
Los tipos complejos no pueden participar en asociaciones. Ninguno de los extremos de una asociación
puede ser un tipo complejo y, por lo tanto, las propiedades de navegación no se pueden definir en tipos
complejos.
Ejemplo
El Entity Framework ADO.net usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición de
esquemas conceptuales (CSDL) para definir los modelos conceptuales. El código CSDL siguiente define un tipo
complejo, Address, con las propiedades de tipo primitivo StreetAddress , City , StateOrProvince , Country y
PostalCode .
Para definir el tipo complejo Address (arriba) como una propiedad en un tipo de entidad, debe declarar el tipo de
propiedad en la definición del tipo de entidad. El código CSDL siguiente declara la propiedad Address como un
tipo complejo en un tipo de entidad (Publisher):
<EntityType Name="Publisher">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Type="Int32" Name="Id" Nullable="false" />
<Property Type="String" Name="Name" Nullable="false" />
<Property Type="BooksModel.Address" Name="Address" Nullable="false" />
<NavigationProperty Name="Books" Relationship="BooksModel.PublishedBy"
FromRole="Publisher" ToRole="Book" />
</EntityType>
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
contenedor de entidades
08/11/2019 • 2 minutes to read • Edit Online
Ejemplo
El diagrama siguiente muestra un modelo conceptual con tres tipos de entidades: Book , Publisher y Author .
Para obtener más información, vea el ejemplo siguiente.
Aunque el diagrama no proporciona información sobre el contenedor de entidades, el modelo conceptual debe
definir un contenedor de entidades. El Entity Framework ADO.net usa un DSL denominado lenguaje de definición
de esquemas conceptuales (CSDL) para definir los modelos conceptuales. El código CSDL siguiente define un
contenedor de entidades para el modelo conceptual mostrado en el diagrama anterior. Tenga en cuenta que el
nombre del contenedor de entidades se define en un atributo XML.
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
clave de entidad
08/11/2019 • 5 minutes to read • Edit Online
Una clave de entidad es una propiedad o un conjunto de propiedades de un tipo de entidad que se usan para
determinar la identidad. Las propiedades que constituyen una entidad se eligen en tiempo de diseño. Los valores
de las propiedades de clave de entidad deben identificar de forma única una instancia de tipo de entidad dentro
de un conjunto de entidades en tiempo de ejecución. Las propiedades que constituyen una clave de entidad se
deben elegir de tal forma que garanticen la unicidad de las instancias de un conjunto de entidades.
Los requisitos para que un conjunto de propiedades sea una clave de entidad son los siguientes:
No puede haber dos claves de entidad idénticas en un conjunto de entidades. Es decir, para dos entidades
cualesquiera dentro de un conjunto de entidades, los valores de todas las propiedades que constituyen
una clave no pueden ser idénticos. Sin embargo, algunos (pero no todos) los valores que constituyen una
clave de entidad pueden ser idénticos.
Una clave de entidad debe constar de un conjunto de propiedades de tipo primitivoque no aceptan
valores NULL e inmutables.
Las propiedades que constituyen una clave de entidad para un tipo de entidad determinado no pueden
cambiar. No se puede designar más de una clave de entidad posible para un tipo de entidad determinado;
no se admiten las claves suplentes.
Cuando una entidad está implicada en una jerarquía de herencia, la entidad raíz debe contener todas las
propiedades que constituyen la clave de entidad, y esta se debe definir en el tipo de entidad raíz. Para
obtener más información, vea Entity Data Model: herencia.
Ejemplo
El diagrama siguiente muestra un modelo conceptual con tres tipos de entidades: Book , Publisher y Author .
Las propiedades de cada tipo de entidad que constituyen su clave de entidad se denotan con "(Key)". Tenga en
cuenta que el tipo de entidad Author tiene una clave de entidad que consta de dos propiedades, Name y
Address .
El Entity Framework ADO.net usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición
de esquemas conceptuales (CSDL) para definir los modelos conceptuales. El código CSDL siguiente define el tipo
de entidad Book mostrado en el diagrama anterior. Observe que la clave de entidad se define haciendo
referencia a la propiedad ISBN del tipo de entidad.
<EntityType Name="Book">
<Key>
<PropertyRef Name="ISBN" />
</Key>
<Property Type="String" Name="ISBN" Nullable="false" />
<Property Type="String" Name="Title" Nullable="false" />
<Property Type="Decimal" Name="Revision" Nullable="false" Precision="29" Scale="29" />
<NavigationProperty Name="Publisher" Relationship="BooksModel.PublishedBy"
FromRole="Book" ToRole="Publisher" />
<NavigationProperty Name="Authors" Relationship="BooksModel.WrittenBy"
FromRole="Book" ToRole="Author" />
</EntityType>
La propiedad ISBN es una opción adecuada para la clave de entidad, ya que el International Standard Book
Number (ISBN) permite identificar un libro de manera inequívoca.
El código CSDL siguiente define el tipo de entidad Author mostrado en el diagrama anterior. Observe que la
clave de entidad consta de dos propiedades, Name y Address .
<EntityType Name="Author">
<Key>
<PropertyRef Name="Name" />
<PropertyRef Name="Address" />
</Key>
<Property Type="String" Name="Name" Nullable="false" />
<Property Type="String" Name="Address" Nullable="false" />
<NavigationProperty Name="Books" Relationship="BooksModel.WrittenBy"
FromRole="Author" ToRole="Book" />
</EntityType>
El uso de Name y Address para la clave de entidad es una opción razonable, ya que no es probable que dos
autores con el mismo nombre vivan en la misma dirección. Sin embargo, esta opción no garantiza por completo
la existencia de claves de entidad únicas en un conjunto de entidades. En este caso, se recomienda la adición de
una propiedad, como AuthorId , que se podría usar para identificar un autor de forma inequívoca.
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
conjunto de entidades
08/11/2019 • 5 minutes to read • Edit Online
Un conjunto de entidades es un contenedor lógico para las instancias de un tipo de entidad y las instancias de
cualquier tipo derivado de ese tipo de entidad. (Para obtener información sobre los tipos derivados, vea Entity
Data Model: herencia). La relación entre un tipo de entidad y un conjunto de entidades es análoga a la relación
entre una fila y una tabla en una base de datos relacional: como una fila, un tipo de entidad describe la
estructura de datos y, como una tabla, un conjunto de entidades contiene instancias de una estructura
determinada. Un conjunto de entidades no es una construcción de modelado de datos, ya que no describe la
estructura de los datos. En su lugar, un conjunto de entidades proporciona una construcción para que un
entorno de hospedaje o de almacenamiento (como Common Language Runtime o una base de datos de SQL
Server) agrupe las instancias del tipo de entidad y se puedan asignar a un almacén de datos.
Un conjunto de entidades se define dentro de un contenedor de entidades, que es una agrupación lógica de
conjuntos de entidades y conjuntos de asociaciones.
Para que una instancia de tipo de entidad exista en un conjunto de entidades, deben cumplirse las condiciones
siguientes:
El tipo de la instancia puede ser el mismo que el tipo de entidad en el que se basa el conjunto de
entidades, o un subtipo del tipo de entidad.
La clave de entidad para la instancia es única en el conjunto de entidades.
La instancia no existe en ningún otro conjunto de entidades.
NOTE
Se pueden definir varios conjuntos de entidades usando el mismo tipo de entidad, pero una instancia de un tipo
de entidad determinado solo puede existir en un conjunto de entidades.
No es necesario definir un conjunto de entidades para cada tipo de entidad de un modelo conceptual.
Ejemplo
El diagrama siguiente muestra un modelo conceptual con tres tipos de entidades: Book , Publisher y Author .
Es posible definir varios conjuntos de entidades por tipo (MEST). El código CSDL siguiente define un contenedor
de entidades con dos conjuntos de entidades para el tipo de entidad Book :
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
tipo de entidad
08/11/2019 • 2 minutes to read • Edit Online
El tipo de entidad es el bloque de creación fundamental para describir la estructura de los datos con el
Entity Data Model (EDM). En un modelo conceptual, un tipo de entidad representa la estructura de
conceptos de nivel superior, como clientes o pedidos. Un tipo de entidad es una plantilla para las instancias
de tipo de entidad. Cada plantilla contiene la información siguiente:
Un nombre único. (Requerido)
Una clave de entidad definida por una o más propiedades. (Requerido)
Datos en forma de propiedades. (Opcional)
Propiedades de navegación que permiten la navegación desde un extremo de una Asociación al otro
extremo. (Opcional)
En una aplicación, una instancia de un tipo de entidad representa un objeto específico (como un cliente o un
pedido concreto). Cada instancia de un tipo de entidad debe tener una clave de entidad única dentro de un
conjunto de entidades.
Dos instancias de tipo de entidad se consideran iguales solo si son del mismo tipo y los valores de sus
claves de entidad son idénticos.
Ejemplo
El diagrama siguiente muestra un modelo conceptual con tres tipos de entidad: Book , Publisher y Author :
Tenga en cuenta que las propiedades de cada tipo de entidad que constituyen su clave de entidad se
denotan con "(Key)".
El Entity Framework ADO.net usa un lenguaje específico de dominio (DSL) denominado lenguaje de
definición de esquemas conceptuales (CSDL) para definir los modelos conceptuales. El siguiente CSDL
define el tipo de entidad Book mostrado en el diagrama anterior.
<EntityType Name="Book">
<Key>
<PropertyRef Name="ISBN" />
</Key>
<Property Type="String" Name="ISBN" Nullable="false" />
<Property Type="String" Name="Title" Nullable="false" />
<Property Type="Decimal" Name="Revision" Nullable="false" Precision="29" Scale="29" />
<NavigationProperty Name="Publisher" Relationship="BooksModel.PublishedBy"
FromRole="Book" ToRole="Publisher" />
<NavigationProperty Name="Authors" Relationship="BooksModel.WrittenBy"
FromRole="Book" ToRole="Author" />
</EntityType>
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
facet
facet
08/11/2019 • 3 minutes to read • Edit Online
Una faceta se usa para agregar detalles a una definición de propiedad de tipo primitivo. Una definición de
propiedad contiene información sobre el tipo de propiedad, pero a menudo es necesario más detalles. Por
ejemplo, un tipo de entidad en un modelo conceptual podría tener una propiedad de tipo String cuyo valor no
se puede establecer en NULL. Las facetas permiten especificar este nivel de detalle.
En la siguiente tabla se describen las facetas que se admiten en EDM.
NOTE
El entorno de tiempo de ejecución que utiliza una implementación de EDM determina los valores exactos y los
comportamientos de las facetas.
ConcurrencyMode Indica que el valor de propiedad se Todas las propiedades de tipo primitivo
debería utilizar para las
comprobaciones de la simultaneidad
optimista.
Nullable Especifica si la propiedad puede tener Todas las propiedades de tipo primitivo
un valor NULL.
Ejemplo
El Entity Framework ADO.net usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición de
esquemas conceptuales (CSDL) para definir los modelos conceptuales. En el ejemplo siguiente CSDL, se define un
tipo de entidad Book . Observe que las facetas se implementan como atributos XML. Los valores de faceta indican
que ninguna propiedad puede estar establecida en NULL, y que los valores Scale y Precision de la propiedad
Revision están establecidos ambos en 29.
<EntityType Name="Book">
<Key>
<PropertyRef Name="ISBN" />
</Key>
<Property Type="String" Name="ISBN" Nullable="false" />
<Property Type="String" Name="Title" Nullable="false" />
<Property Type="Decimal" Name="Revision" Nullable="false" Precision="29" Scale="29" />
<NavigationProperty Name="Publisher" Relationship="BooksModel.PublishedBy"
FromRole="Book" ToRole="Publisher" />
<NavigationProperty Name="Authors" Relationship="BooksModel.WrittenBy"
FromRole="Book" ToRole="Author" />
</EntityType>
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
propiedad de clave externa
08/11/2019 • 2 minutes to read • Edit Online
Una propiedad de clave externa en el Entity Data Model (EDM) es una propiedad de tipo primitivo (o un conjunto
de propiedades de tipo primitivo) en un tipo de entidad que contiene la clave de entidad de otro tipo de entidad.
Una propiedad de clave externa es análoga a una columna de clave externa de una base de datos relacional. Del
mismo modo que las columnas de clave externa se utilizan en una base de datos relacional para crear relaciones
entre las filas de las tablas, las propiedades de clave externa en un modelo conceptual se utilizan para establecer
asociaciones entre tipos de entidad. Una restricción de integridad referencial se utiliza para definir una asociación
entre dos tipos de entidad cuando uno de los tipos tiene una propiedad de clave externa.
Ejemplo
El diagrama siguiente muestra un modelo conceptual con tres tipos de entidades: Book , Publisher y Author . El
tipo de entidad Book tiene una propiedad, PublisherId , que hace referencia a la clave de entidad del tipo de
entidad Publisher cuando se define una restricción de integridad referencial en la asociación PublishedBy .
El Entity Framework ADO.net usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición de
esquemas conceptuales (CSDL) para definir los modelos conceptuales. El código CSDL siguiente usa la propiedad
de clave externa PublisherId para definir una restricción de integridad referencial en la asociación PublishedBy
incluida en el modelo conceptual mostrado anteriormente.
<Association Name="PublishedBy">
<End Type="BooksModel.Book" Role="Book" Multiplicity="*" >
</End>
<End Type="BooksModel.Publisher" Role="Publisher" Multiplicity="1" />
<ReferentialConstraint>
<Principal Role="Publisher">
<PropertyRef Name="Id" />
</Principal>
<Dependent Role="Book">
<PropertyRef Name="PublisherId" />
</Dependent>
</ReferentialConstraint>
</Association>
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
función declarada por el modelo
23/10/2019 • 2 minutes to read • Edit Online
Una función declarada por el modelo es una función que se declara en un modelo conceptual, pero que no está
definida en ese modelo conceptual. La función se podría definir en el entorno de almacenamiento u hospedaje. Por
ejemplo, una función declarada por modelo se podría asignar a una función definida en una base de datos,
exponiendo así la funcionalidad de servidor en el modelo conceptual.
La declaración de una función declarada por modelo contiene la siguiente información:
Nombre de la función. (Necesario)
El tipo del valor devuelto. (Opcional)
NOTE
Si no se especifica ningún valor devuelto, el tipo de valor devuelto es void.
Ejemplo
El Entity Framework ADO.net usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición de
esquemas conceptuales (CSDL) para definir los modelos conceptuales. En CSDL, una implementación de una
función declarada por modelo es una importación de función (mediante el elemento FunctionImport). El siguiente
CSDL define un contenedor de la entidad con una definición de importación de función. Tenga en cuenta que el
tipo de valor devuelto es void porque no se especifica ningún tipo de valor devuelto.
<FunctionImport Name="UpdatePublisher">
<Parameter Name="PublisherId" Mode="In" Type="Int32" />
<Parameter Name="PublisherName" Mode="In" Type="String" />
</FunctionImport>
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
función definida por el modelo
08/11/2019 • 2 minutes to read • Edit Online
Una función definida por el modelo es una función que se define en un modelo conceptual. El cuerpo de una
función definida por el modelo se expresa en Entity SQL, lo que permite expresar la función independientemente
de las reglas o los lenguajes admitidos en el origen de datos.
La definición para una función definida por el modelo contiene la información siguiente:
El nombre de la función. (Necesario)
El tipo del valor devuelto. (Opcional)
NOTE
Si no se especifica ningún tipo de valor devuelto, este es void.
Ejemplo
El diagrama siguiente muestra un modelo conceptual con tres tipos de entidades: Book , Publisher y Author .
El Entity Framework ADO.net usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición de
esquemas conceptuales (CSDL) para definir los modelos conceptuales. El código CSDL siguiente define una función
en el modelo conceptual que devuelve el número de años transcurridos desde la publicación de una instancia de
Book (en el diagrama anterior).
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
Entity Data Model: Tipos de datos primitivos
Propiedad de navegación
10/02/2020 • 3 minutes to read • Edit Online
Una propiedad de navegación es una propiedad opcional en un tipo de entidad que permite la navegación
desde un extremo de una Asociación al otro extremo. A diferencia de otras propiedades, las propiedades de
navegación no contienen datos.
Una definición de propiedad de desplazamiento incluye lo siguiente:
Un nombre. (Requerido)
La asociación que navega. (Requerido)
Los extremos de la asociación que navega. (Requerido)
Las propiedades de navegación son opcionales en ambos tipos de entidad de los extremos de una asociación. Si
define una propiedad de navegación en un tipo de entidad del extremo de una asociación, no tiene que definir
una propiedad de navegación en el tipo de entidad del otro extremo de la asociación.
El tipo de datos de una propiedad de navegación viene determinado por la multiplicidad de su extremode la
Asociación remota. Por ejemplo, supongamos que una propiedad de navegación, OrdersNavProp , existe en un
tipo de entidad Customer y navega a una asociación uno a varios entre Customer y Order . Dado que el
extremo remoto de la Asociación para la propiedad de navegación tiene la multiplicidad de muchos (*), su tipo
de datos es una colección (de Order ). De igual forma, si una propiedad de navegación, CustomerNavProp , existe
en el tipo de entidad Order , su tipo de datos sería Customer , porque la multiplicidad del extremo remoto es
uno (1).
Ejemplo
El diagrama siguiente muestra un modelo conceptual con tres tipos de entidades: Book , Publisher y Author .
Las propiedades de navegación Publisher y Authors se definen en el tipo de entidad Book. La propiedad de
navegación Books se define en el tipo de entidad Publisher y el tipo de entidad Author .
El Entity Framework ADO.net usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición
de esquemas conceptuales (CSDL) para definir los modelos conceptuales. El siguiente CSDL define el tipo de
entidad Book mostrado en el diagrama anterior.
<EntityType Name="Book">
<Key>
<PropertyRef Name="ISBN" />
</Key>
<Property Type="String" Name="ISBN" Nullable="false" />
<Property Type="String" Name="Title" Nullable="false" />
<Property Type="Decimal" Name="Revision" Nullable="false" Precision="29" Scale="29" />
<NavigationProperty Name="Publisher" Relationship="BooksModel.PublishedBy"
FromRole="Book" ToRole="Publisher" />
<NavigationProperty Name="Authors" Relationship="BooksModel.WrittenBy"
FromRole="Book" ToRole="Author" />
</EntityType>
Los atributos XML se utilizan para comunicar la información necesaria para definir una propiedad de
navegación: el atributo Name contiene el nombre de la propiedad, Relationship contiene el nombre de la
asociación a la que navega y FromRole y ToRole contienen los extremos de la asociación.
Consulte también
Conceptos clave de Entity Data Model
Entity Data Model
Relaciones, propiedades de navegación y claves externas
Propiedad
08/11/2019 • 4 minutes to read • Edit Online
Las propiedades son los bloques de creación fundamentales de tipos de entidad y tipos complejos. Las
propiedades definen la forma y características de datos que una instancia del tipo de entidad o la instancia del
tipo complejo contendrá. Las propiedades en un modelo conceptual son análogas a las propiedades definidas
en una clase. Del mismo modo que las propiedades en una clase definen la forma de la clase y proporcionan
información sobre los objetos, las propiedades en un modelo conceptual definen la forma de un tipo de
entidad y proporcionan información sobre las instancias del tipo de entidad.
NOTE
Las propiedades, tal y como se describen en este tema, son diferentes de las propiedades de navegación. Para obtener
más información, vea propiedades de navegación.
NOTE
Un tipo complejo puede, por sí mismo, tener propiedades complejas.
Ejemplo
El diagrama siguiente muestra un modelo conceptual con tres tipos de entidades: Book , Publisher y Author
. Cada tipo de entidad tiene varias propiedades, aunque la información de tipo para cada propiedad no se
muestra en el diagrama. Las propiedades que son claves de entidad se denotan con (Key).
El Entity Framework ADO.net usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición
de esquemas conceptuales (CSDL) para definir los modelos conceptuales. En el siguiente CSDL se define el
tipo de entidad Book (como se muestra en el diagrama anterior) y se indica el tipo y nombre de cada
propiedad utilizando atributos XML. Una faceta opcional, Nullable , también se define utilizando un atributo
de XML.
<EntityType Name="Book">
<Key>
<PropertyRef Name="ISBN" />
</Key>
<Property Type="String" Name="ISBN" Nullable="false" />
<Property Type="String" Name="Title" Nullable="false" />
<Property Type="Decimal" Name="Revision" Nullable="false" Precision="29" Scale="29" />
<NavigationProperty Name="Publisher" Relationship="BooksModel.PublishedBy"
FromRole="Book" ToRole="Publisher" />
<NavigationProperty Name="Authors" Relationship="BooksModel.WrittenBy"
FromRole="Book" ToRole="Author" />
</EntityType>
Es posible que una de las propiedades mostradas en el diagrama sea una propiedad de tipo complejo. Por
ejemplo, la propiedad Address en el tipo de entidad Publisher podría ser una propiedad de tipo complejo
compuesta de varias propiedades escalares, como StreetAddress , City , StateOrProvince , Country y
PostalCode . La representación CSDL de un tipo complejo como el anterior sería como sigue:
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
restricción de integridad referencial
08/11/2019 • 3 minutes to read • Edit Online
Una restricción de integridad referencial en el Entity Data Model (EDM) es similar a una restricción de integridad
referencial en una base de datos relacional. Del mismo modo que una columna (o columnas) de una tabla de base
de datos puede hacer referencia a la clave principal de otra tabla, una propiedad (o propiedades) de un tipo de
entidad puede hacer referencia a la clave de entidad de otro tipo de entidad. El tipo de entidad al que se hace
referencia se denomina extremo principal de la restricción. El tipo de entidad que hace referencia al extremo
principal se denomina extremo dependiente de la restricción.
Una restricción de integridad referencial se define como parte de una Asociación entre dos tipos de entidad. La
definición para una restricción de integridad referencial especifica la siguiente información:
El extremo principal de la restricción. Es un tipo de entidad a cuya clave de entidad hace referencia el
extremo dependiente.
La clave de entidad del extremo principal.
El extremo dependiente de la restricción. Es un tipo de entidad que tiene una o varias propiedades que
hacen referencia a la clave de entidad del extremo principal.
La propiedad o propiedades que hacen la referencia del extremo dependiente.
El propósito de las restricciones de integridad referencial de EDM es garantizar la existencia de asociaciones
válidas. Para obtener más información, consulte Foreign Key Property.
Ejemplo
El diagrama siguiente muestra un modelo conceptual con dos asociaciones: WrittenBy y PublishedBy . El tipo de
entidad Book tiene una propiedad, PublisherId , que hace referencia a la clave de entidad del tipo de entidad
Publisher cuando se define una restricción de integridad referencial en la asociación PublishedBy .
El Entity Framework ADO.net usa un lenguaje específico de dominio (DSL) denominado lenguaje de definición de
esquemas conceptuales (CSDL) para definir los modelos conceptuales. El código CSDL siguiente define una
restricción de integridad referencial en la asociación PublishedBy mostrada en el modelo conceptual
anteriormente citado.
<Association Name="PublishedBy">
<End Type="BooksModel.Book" Role="Book" Multiplicity="*" >
</End>
<End Type="BooksModel.Publisher" Role="Publisher" Multiplicity="1" />
<ReferentialConstraint>
<Principal Role="Publisher">
<PropertyRef Name="Id" />
</Principal>
<Dependent Role="Book">
<PropertyRef Name="PublisherId" />
</Dependent>
</ReferentialConstraint>
</Association>
Vea también
Conceptos clave de Entity Data Model
Entity Data Model
Oracle y ADO.NET
05/02/2020 • 3 minutes to read • Edit Online
NOTE
Los tipos de System.Data.OracleClient están en desuso. Los tipos seguirán estando admitidos en la versión actual de .NET
Framework, pero se quitarán en una versión posterior. Microsoft recomienda usar un proveedor de Oracle de otro
fabricante.
En esta sección se describen características y comportamientos específicos del proveedor de datos de .NET
Framework para Oracle.
El proveedor de datos de .NET Framework para Oracle proporciona acceso a una base de datos de Oracle
mediante Oracle Call Interface (OCI), tal y como lo proporciona el software cliente de Oracle. La funcionalidad del
proveedor de datos está diseñada para ser similar a la de los .NET Framework proveedores de datos para SQL
Server, OLE DB y ODBC.
Para utilizar el proveedor de datos de .NET Framework para Oracle, una aplicación debe hacer referencia al
espacio de nombres System.Data.OracleClient como se indica a continuación:
Imports System.Data.OracleClient
using System.Data.OracleClient;
También debe incluir una referencia a la DLL cuando compile el código. Por ejemplo, si compila un programa C#,
la línea de comandos debe incluir:
csc /r:System.Data.OracleClient.dll
Esta sección
Requisitos del sistema
Describe los requisitos para usar el proveedor de datos de .NET Framework para Oracle y describe una serie de
problemas que se deben tener en cuenta al utilizarlos.
Objetos BFILE de Oracle
Describe la clase OracleBFile, que se utiliza para trabajar con el tipo de datos BFILE de Oracle.
Objetos LOB de Oracle
Describe la clase OracleLob, que se utiliza para trabajar con tipos de datos LOB de Oracle.
Parámetros REF CURSOR de Oracle
Describe la compatibilidad con el tipo de datos REF CURSOR de Oracle.
Tipos de Oracle
Describe las estructuras que puede utilizar para trabajar con tipos de datos de Oracle, como OracleNumber y
OracleString.
Secuencias de Oracle
Describe la compatibilidad para recuperar los valores de clave de secuencia de Oracle que genera el servidor.
Asignaciones de tipos de datos de Oracle
Enumera los tipos de datos de Oracle y sus asignaciones al OracleDataReader.
Transacciones distribuidas de Oracle
Describe cómo se inscribe automáticamente el objeto OracleConnection en una transacción distribuida si se
determina que hay una transacción activa.
Secciones relacionadas
Proteger aplicaciones de ADO.NET
Describe algunas recomendaciones de codificación segura para utilizar ADO.NET.
Objetos DataSet, DataTable y DataView
Describe cómo crear y usar DataSets , DataSets con establecimiento de tipos, DataTables y DataViews .
Recuperar y modificar datos en ADO.NET
Describe cómo trabajar con datos XML en ADO.NET.
SQL Server y ADO.NET
Describe cómo trabajar con las características y la funcionalidad específicas de SQL Server.
Objetos DbProviderFactory
Describe clases genéricas que permiten escribir código independiente del proveedor en ADO.NET.
Vea también
ADO.NET
Información general sobre ADO.NET
Requisitos del sistema para el proveedor de datos
.NET Framework para Oracle
21/03/2020 • 5 minutes to read • Edit Online
El proveedor de datos .NET Framework para Oracle requiere Microsoft Data Access Components (MDAC), versión
2.6 o posterior. Se recomienda MDAC 2.8 SP1.
También debe tener instalado Oracle 8i Release 3 (8.1.7) Client o posterior.
El software Oracle Client anterior a la versión Oracle 9i no puede tener acceso a las bases de datos UTF16 dado que
UTF16 es una nueva característica en Oracle 9i. Para utilizar esta característica, deberá actualizar el software de
cliente a Oracle 9i o posterior.
para inicializar las bibliotecas de cliente de Oracle en modo UTF-16. De esta manera, las bibliotecas de cliente de
Oracle aceptarán UTF-16 (que es muy parecido a UCS-2) en lugar de cadenas de varios bytes. Como consecuencia,
el proveedor de datos para Oracle puede trabajar siempre con cualquier página de códigos Oracle sin necesidad de
trabajo de conversión adicional. Esta configuración sólo funciona si utiliza clientes Oracle 9i para comunicarse con
una base de datos Oracle 9i con el juego de caracteres alternativo de AL16UTF16. Cuando un cliente De Oracle 9i
se comunica con un servidor Oracle 9i, se requieren recursos adicionales para convertir los valores de
CommandText Unicode en el conjunto de caracteres multibyte adecuado que utiliza el servidor Oracle9i. Esto se
puede evitar si sabe que tiene la configuración segura agregando Unicode=True a la cadena de conexión.
Mezcla de versiones de Oracle Client y Oracle Server
Los clientes de Oracle 8i no pueden acceder a datos NCHAR, NVARCHAR2 o NCLOB en bases de datos Oracle 9i
cuando el juego de caracteres nacional del servidor se especifica como AL16UTF16 (la configuración
predeterminada para Oracle 9i). Como hasta Oracle 9i no se introdujo la compatibilidad con el juego de caracteres
UTF-16, los clientes Oracle 8i no pueden leerlo.
Trabajo con datos UTF -8
Para definir el juego de caracteres alternativo, establezca la clave del Registro
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOMEID\NLS_LANG en UTF8. Para obtener más información, vea
las notas de instalación de Oracle correspondientes a su plataforma. La opción predeterminada es el juego de
caracteres principal del idioma con el que va a instalar el software Oracle Client. Si no establece el idioma para que
coincida con el juego de caracteres del idioma nacional de la base de datos a la que se va a conectar, ocasionará
que los enlaces de parámetros y columnas envíen o reciban datos con el juego de caracteres principal de la base de
datos, y no con el juego de caracteres nacional.
OracleLob sólo puede actualizar caracteres completos.
Por motivos de OracleLob usabilidad, el objeto hereda de la clase Stream de .NET Framework y proporciona
métodos ReadByte y WriteByte. También implementa métodos, como CopyTo y Erase, que funcionan en
secciones de objetos LOB de Oracle. Por el contrario, el software cliente de Oracle proporciona una serie de API
para trabajar con caracteres LOB s (CLOB y NCLOB ). No obstante, estas API sólo funcionan en caracteres
completos. Debido a esta diferencia, el proveedor de datos para Oracle implementa la compatibilidad con Read y
ReadByte para trabajar con datos UTF-16 de una manera byte. Sin embargo, los otros métodos del objeto
OracleLob solo permiten operaciones de caracteres completos.
Consulte también
Oracle y ADO.NET
Información general de ADO.NET
Objetos BFILE de Oracle
21/03/2020 • 4 minutes to read • Edit Online
El proveedor de datos .NET Framework para Oracle incluye la clase OracleBFile, que se utiliza para trabajar con el
tipo de datos BFile de Oracle.
El tipo de datos BFILE de Oracle es un tipo de datos LOB de Oracle que contiene una referencia a datos binarios
con un tamaño máximo de 4 gigabytes. Un BFILE de Oracle difiere de otros tipos de datos LOB de Oracle en que
sus datos se almacenan en un archivo físico en el sistema operativo en lugar de en el servidor. Tenga en cuenta que
el tipo de datos BFILE proporciona acceso de solo lectura a los datos.
Otras características de un tipo de datos BFILE que lo distinguen de un tipo de datos LOB son que:
contiene datos no estructurados.
admite el troceo en el servidor.
utiliza semántica de copia de referencia. Por ejemplo, si realiza una operación de copia en un archivo BFILE ,
solo se copia el localizador BFILE (que es una referencia al archivo). Los datos del archivo no se copian.
El tipo de datos BFILE se debe usar para hacer referencia a LOB que son de gran tamaño y, por lo tanto, no es
práctico almacenar en la base de datos. Más sobrecarga de cliente, servidor y comunicación implica cuando se usa
un tipo de datos BFILE en comparación con el tipo de datos LOB. Es más eficaz acceder a un Archivo BFILE si
solo necesita obtener una pequeña cantidad de datos. En cambio, si necesita obtener el objeto entero, es más
eficiente tener acceso a los LOB residentes en la base de datos.
Cada objeto OracleBFile no NULL está asociado a dos entidades que definen la ubicación del archivo físico
subyacente:
1. Un objeto DIRECTORY de Oracle, que es un alias de base de datos de un directorio del sistema de archivos, y
2. el nombre de archivo del archivo físico subyacente, que se encuentra en el directorio asociado con el objeto
DIRECTORY.
Ejemplo
En el siguiente ejemplo de C- se muestra cómo crear un archivo BFILE en una tabla de Oracle y, a continuación,
recuperarlo en forma de un OracleBFile objeto. En el ejemplo OracleDataReader se muestra cómo utilizar el
objeto y los métodos OracleBFile Seek y Read. Tenga en cuenta que para utilizar este ejemplo, primero\debe
crear un directorio denominado "c: .bfiles" y el archivo denominado "MyFile.jpg" en el servidor de Oracle.
using System;
using System.IO;
using System.Data;
using System.Data.OracleClient;
connection.Close();
}
Consulte también
Oracle y ADO.NET
Información general de ADO.NET
Objetos LOB de Oracle
21/03/2020 • 6 minutes to read • Edit Online
El proveedor de datos de OracleLob .NET Framework para Oracle incluye la clase, que se utiliza para trabajar con
tipos de datos LOB de Oracle.
Un OracleLob puede ser OracleType uno de estos tipos de datos:
Un OracleLob difiere OracleBFile de un en que los datos se almacenan en el servidor en lugar de en un archivo
físico en el sistema operativo. También puede ser un objeto de lectura y escritura, a diferencia de un OracleBFile ,
que siempre es de solo lectura.
using System;
using System.IO;
using System.Text;
using System.Data;
using System.Data.OracleClient;
// LobExample
public class LobExample
{
public static int Main(string[] args)
{
//Create a connection.
OracleConnection conn = new OracleConnection(
"Data Source=Oracle8i;Integrated Security=yes");
using(conn)
{
//Open a connection.
conn.Open();
OracleCommand cmd = conn.CreateCommand();
//Read example.
ReadLobExample(cmd);
//Write example
WriteLobExample(cmd);
}
return 1;
}
// ReadLobExample
public static void ReadLobExample(OracleCommand cmd)
{
int actual = 0;
// Table Schema:
// "CREATE TABLE tablewithlobs (a int, b BLOB, c CLOB, d NCLOB)";
// "INSERT INTO tablewithlobs values (1, 'AA', 'AAA', N'AAAA')";
// Select some data.
cmd.CommandText = "SELECT * FROM tablewithlobs";
OracleDataReader reader = cmd.ExecuteReader();
using(reader)
{
//Obtain the first row of data.
reader.Read();
// WriteLobExample
public static void WriteLobExample(OracleCommand cmd)
{
//Note: Updating LOB data requires a transaction.
cmd.Transaction = cmd.Connection.BeginTransaction();
// Obtain a LOB.
OracleLob blob = reader.GetOracleLob(1/*0:based ordinal*/);
// CreateTempLob
public static OracleLob CreateTempLob(
OracleCommand cmd, OracleType lobtype)
{
//Oracle server syntax to obtain a temporary LOB.
cmd.CommandText = "DECLARE A " + lobtype + "; "+
"BEGIN "+
"DBMS_LOB.CREATETEMPORARY(A, FALSE); "+
":LOC := A; "+
"END;";
// CreateTable
public static void CreateTable(OracleCommand cmd)
{
// Table Schema:
// "CREATE TABLE tablewithlobs (a int, b BLOB, c CLOB, d NCLOB)";
// "INSERT INTO tablewithlobs VALUES (1, 'AA', 'AAA', N'AAAA')";
try
{
cmd.CommandText = "DROP TABLE tablewithlobs";
cmd.ExecuteNonQuery();
}
catch(Exception)
{
}
cmd.CommandText =
"CREATE TABLE tablewithlobs (a int, b BLOB, c CLOB, d NCLOB)";
cmd.ExecuteNonQuery();
cmd.CommandText =
"INSERT INTO tablewithlobs VALUES (1, 'AA', 'AAA', N'AAAA')";
cmd.ExecuteNonQuery();
}
}
OracleTransaction tx = conn.BeginTransaction();
tx.Commit();
Consulte también
Oracle y ADO.NET
Información general de ADO.NET
Parámetros REF CURSOR de Oracle
23/10/2019 • 3 minutes to read • Edit Online
El proveedor de datos de .NET Framework para Oracle admite el tipo de datos ref cursor de Oracle. Cuando
utilice el proveedor de datos para trabajar con cursores REF CURSOR de Oracle, debe tener en cuenta los
siguientes comportamientos.
NOTE
Algunos de ellos difieren de los del proveedor Microsoft OLE DB para Oracle (MSDAORA).
Por motivos de rendimiento, el proveedor de datos para Oracle no enlaza automáticamente los tipos de
datos ref cursor , como hace MSDAORA, a menos que se especifiquen explícitamente.
El proveedor de datos no admite ninguna secuencia de escape ODBC, lo que incluye el escape {resultset}
usado para especificar parámetros REF CURSOR.
Para ejecutar un procedimiento almacenado que devuelve los cursores REF cursor, debe definir los
parámetros de OracleParameterCollection con un OracleType de cursor y un Direction de Output . El
proveedor de datos admite el enlace de cursores REF CURSOR sólo como parámetros de salida; no los
admite como parámetros de entrada.
No se permite la obtención de un OracleDataReader del valor del parámetro. Los valores son del tipo
DBNull después de la ejecución del comando.
El único valor de enumeración de CommandBehavior que funciona con cursores REF cursor (por
ExecuteReaderejemplo, al llamar a) es CloseConnection ; se omiten todos los demás.
El orden de los CURSOres REF CURSOR en el objeto OracleDataReader depende del orden de los
parámetros de OracleParameterCollection . Se omite la propiedad ParameterName.
No se admite el tipo de datos de la tabla PL/SQL. No obstante, los cursores REF CURSOR resultan más
eficientes. Si debe utilizar un tipo de datos de tabla , use el proveedor de datos OLE DB .net con
MSDAORA.
En esta sección
Ejemplos de REF CURSOR
Contiene tres ejemplos en los que se muestra el uso de cursores REF CURSOR.
Parámetros REF CURSOR en un objeto OracleDataReader
Muestra cómo ejecutar un procedimiento almacenado PL/SQL que devuelve un parámetro REF CURSOR y lee el
valor como OracleDataReader .
Recuperación de datos desde varios parámetros REF CURSOR utilizando un objeto OracleDataReader
Muestra cómo ejecutar un procedimiento almacenado PL/SQL que devuelve dos parámetros REF CURSOR y Lee
los valores mediante un OracleDataReader .
Relleno de un conjunto de datos utilizando uno o varios parámetros REF CURSOR
Muestra cómo ejecutar un procedimiento almacenado PL/SQL que devuelve dos parámetros REF CURSOR y llena
un DataSet con las filas que se devuelven.
Vea también
Oracle y ADO.NET
Información general sobre ADO.NET
Ejemplos de REF CURSOR
21/03/2020 • 3 minutes to read • Edit Online
Los ejemplos de cursores REF CURSOR constan de los siguientes tres ejemplos de Microsoft Visual Basic que
muestran el uso de los cursores REF CURSOR.
Parámetros REF CURSOR en un objeto OracleDataReader En este ejemplo se ejecuta un procedimiento almacenado
PL/SQL que devuelve un parámetro REF CURSOR y lee el valor
como un OracleDataReader.
Recuperar datos desde varios parámetros REF CURSOR En este ejemplo se ejecuta un procedimiento almacenado
utilizando un objeto OracleDataReader PL/SQL que devuelve dos parámetros REF CURSOR y lee los
valores mediante OracleDataReader .
Rellenar un conjunto de datos utilizando uno o varios En este ejemplo se ejecuta un procedimiento almacenado
parámetros REF CURSOR PL/SQL que devuelve dos parámetros REF CURSOR y llena un
DataSet con las filas que se devuelven.
Para utilizar estos ejemplos, puede que tenga que crear las tablas de Oracle, y deberá crear un paquete PL/SQL y el
cuerpo del paquete.
ELSE
OPEN V_CURSOR FOR
SELECT EMP.EMPNO, EMP.ENAME, DEPT.DEPTNO, DEPT.DNAME
FROM EMP, DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO;
END IF;
IO_CURSOR := V_CURSOR;
END OPEN_ONE_CURSOR;
Consulte también
Parámetros REF CURSOR de Oracle
Información general de ADO.NET
Parámetros REF CURSOR en un objeto
OracleDataReader
23/10/2019 • 2 minutes to read • Edit Online
En este ejemplo de Microsoft Visual Basic se ejecuta un procedimiento almacenado PL/SQL que devuelve un
parámetro REF CURSOR, y se lee el valor mediante un OracleDataReader.
conn.Open()
cmd.Connection = conn
cmd.CommandText = "CURSPKG.OPEN_ONE_CURSOR"
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add(New OracleParameter(
"N_EMPNO", OracleType.Number)).Value = 7369
cmd.Parameters.Add(New OracleParameter(
"IO_CURSOR", OracleType.Cursor)).Direction = ParameterDirection.Output
rdr = cmd.ExecuteReader()
While (rdr.Read())
REM do something with the values
End While
rdr.Close()
End Using
End Sub
Vea también
Parámetros REF CURSOR de Oracle
Información general sobre ADO.NET
Recuperar datos desde varios parámetros REF
CURSOR utilizando un objeto OracleDataReader
21/03/2020 • 2 minutes to read • Edit Online
En este ejemplo de Microsoft Visual Basic se ejecuta un procedimiento almacenado PL/SQL que devuelve dos
parámetros REF CURSOR, y se leen los valores mediante un OracleDataReader.
conn.Open()
cmd.Connection = conn
cmd.CommandText = "CURSPKG.OPEN_TWO_CURSORS"
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add(New OracleParameter( _
"EMPCURSOR", OracleType.Cursor)).Direction = _
ParameterDirection.Output
cmd.Parameters.Add(New OracleParameter(_
"DEPTCURSOR", OracleType.Cursor)).Direction = _
ParameterDirection.Output
rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
While (rdr.Read())
REM do something with the values from the EMP table
End While
rdr.NextResult()
While (rdr.Read())
REM do something with the values from the DEPT table
End While
rdr.Close()
End Using
End Sub
Consulte también
Parámetros REF CURSOR de Oracle
Información general de ADO.NET
Rellenar un conjunto de datos utilizando uno o varios
parámetros REF CURSOR
23/10/2019 • 2 minutes to read • Edit Online
En este ejemplo de Microsoft Visual Basic se ejecuta un procedimiento almacenado PL/SQL que devuelve dos
parámetros REF CURSOR y se rellena un DataSet con las filas que se devuelven.
cmd.Connection = conn
cmd.CommandText = "CURSPKG.OPEN_TWO_CURSORS"
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add(New OracleParameter( _
"EMPCURSOR", OracleType.Cursor)).Direction = _
ParameterDirection.Output
cmd.Parameters.Add(New OracleParameter( _
"DEPTCURSOR", OracleType.Cursor)).Direction = _
ParameterDirection.Output
ds.Relations.Add("EmpDept", ds.Tables("Dept").Columns("Deptno"), _
ds.Tables("Emp").Columns("Deptno"), False)
DataGrid1.DataSource = ds.Tables("Dept")
End Using
Vea también
Parámetros REF CURSOR de Oracle
Información general sobre ADO.NET
Tipos de Oracle
21/03/2020 • 2 minutes to read • Edit Online
El proveedor de datos .NET Framework para Oracle incluye varias estructuras que se pueden utilizar para trabajar
con tipos de datos de Oracle. Por ejemplo, OracleNumber y OracleString.
NOTE
Para ver una lista completa de estas estructuras, vea System.Data.OracleClient.
try
{
myCommand.CommandText = "SELECT * from OracleTypesTable";
OracleDataReader oracledatareader1 = myCommand.ExecuteReader();
oracledatareader1.Read();
//Using the oracle specific getters for each type is faster than
//using GetOracleValue.
Consulte también
Oracle y ADO.NET
Información general de ADO.NET
Secuencias de Oracle
21/03/2020 • 5 minutes to read • Edit Online
El proveedor de datos .NET Framework para Oracle proporciona compatibilidad para recuperar los valores clave de
secuencia de Oracle que genera el servidor después de realizar inserciones con OracleDataAdapter.
SQL Server y Oracle admiten la creación de columnas de incremento automático que pueden designarse como
claves principales. Estos valores los genera el servidor cuando se agregan filas a una tabla. En SQL Server se
establece la propiedad Identity de una columna; en Oracle se crea una secuencia. La diferencia entre las columnas
de incremento automático de SQL Server y las secuencias de Oracle es la siguiente:
En SQL Server, marca una columna como columna de incremento automático y SQL Server genera de
forma automática nuevos valores para la columna cuando se inserta una nueva fila.
En Oracle, para generar nuevos valores en una columna de la tabla crea una secuencia, pero no existe
vínculo directo entre la secuencia y la tabla o la columna. Las secuencias de Oracle son objetos, de la misma
forma que las tablas o los procedimientos almacenados.
Cuando crea una secuencia en una base de datos de Oracle, puede definir su valor inicial y el incremento entre los
valores. También puede consultar si existen nuevos valores en la secuencia antes de enviar nuevas filas. Esto
implica que el código puede reconocer los valores clave de las nuevas filas antes de insertarlas en la base de datos.
Para obtener más información sobre la creación de columnas de incremento automático mediante SQL Server y
ADO.NET, vea Recuperar valores de identidad o numeración automática y Crear columnas de incremento
automático.
Ejemplo
En el siguiente ejemplo de C# se muestra cómo puede recuperar nuevos valores de secuencia de una base de datos
de Oracle. El ejemplo hace referencia a la secuencia de la consulta INSERT INTO utilizada para enviar nuevas filas y,
a continuación, devuelve el valor de secuencia que se genera mediante la cláusula RETURNING introducida en
Oracle10g. El ejemplo agrega una serie de filas nuevas pendientes en un objeto DataTable mediante el uso de la
funcionalidad de incremento automático de ADO.NET para generar "marcadores de posición" de valores clave
principales. Tenga en cuenta que el valor de incremento que genera ADO.NET para la nueva fila es sólo un
"marcador de posición". Esto significa que la base de datos puede generar valores distintos de los que genera
ADO.NET.
Antes de enviar las inserciones pendientes a la base de datos, el ejemplo muestra el contenido de las filas. A
continuación, el código crea un nuevo objeto OracleDataAdapter y establece sus propiedades InsertCommand y
UpdateBatchSize. El ejemplo también proporciona la lógica para devolver los valores que genera el servidor
mediante parámetros de salida. A continuación, ejecuta la actualización para enviar las filas pendientes y muestra el
contenido del objeto DataTable.
cmd.CommandText =
"SELECT ID, OtherColumn FROM SequenceTest_Table";
OracleDataAdapter da = new OracleDataAdapter(cmd);
da.InsertCommand = new OracleCommand(insertString, conn);
da.InsertCommand.Parameters.Add(":ID", OracleType.Int32, 0, "ID");
da.InsertCommand.Parameters[0].Direction = ParameterDirection.Output;
da.InsertCommand.Parameters.Add(":OtherColumn", OracleType.VarChar, 255, "OtherColumn");
da.InsertCommand.UpdatedRowSource = UpdateRowSource.OutputParameters;
da.UpdateBatchSize = 10;
da.Update(testTable);
Consulte también
Oracle y ADO.NET
Información general de ADO.NET
Asignaciones de tipos de datos de Oracle
23/10/2019 • 6 minutes to read • Edit Online
En la siguiente tabla se enumeran los tipos de datos de Oracle y sus asignaciones al OracleDataReader.
T IP O DE DATO S DE . N ET T IP O DE DATO S
F RA M EW O RK DEVUELTO O RA C L EC L IEN T DEVUELTO
POR POR
O RA C L EDATA REA DER. GET VA O RA C L EDATA REA DER. GETO R
T IP O DE DATO S DE O RA C L E L UE A C L EVA L UE C O M EN TA RIO S
En la tabla siguiente se enumeran los tipos de datos de Oracle y los tipos de datos .NET Framework
OracleType(System. Data. DbType y) que se van a usar al enlazarlos como parámetros.
EN UM ERA C IÓ N
EN UM ERA C IÓ N DBT Y P E O RA C L ET Y P E PA RA
PA RA EN L A Z A R C O M O UN EN L A Z A R C O M O UN
T IP O DE DATO S DE O RA C L E PA RÁ M ET RO PA RÁ M ET RO C O M EN TA RIO S
EN UM ERA C IÓ N
EN UM ERA C IÓ N DBT Y P E O RA C L ET Y P E PA RA
PA RA EN L A Z A R C O M O UN EN L A Z A R C O M O UN
T IP O DE DATO S DE O RA C L E PA RÁ M ET RO PA RÁ M ET RO C O M EN TA RIO S
FLOAT Single, Double, decimal Float, Double, número Sizedetermina los datos
System. Data. DBType y
OracleType.
INTEGER SByte, Int16, Int32, SByte, Int16, Int32, Sizedetermina los datos
Int64, Decimal Number System. Data. DBType y
OracleType.
ENTERO SIN SIGNO Byte, UInt16, UInt32, Byte, UInt16, Uint32, Sizedetermina los datos
UInt64, Decimal número System. Data. DBType y
OracleType.
Vea también
Oracle y ADO.NET
Información general sobre ADO.NET
Transacciones distribuidas de Oracle
29/10/2019 • 2 minutes to read • Edit Online
El objeto OracleConnection se inscribe automáticamente en una transacción distribuida si determina que hay una
transacción activa. La inscripción automática en transacciones tiene lugar cuando se abre la conexión o se recupera
del grupo de conexiones. Para deshabilitar la inscripción automática en transacciones existentes, especifique
Enlist=false
Vea también
Oracle y ADO.NET
Información general sobre ADO.NET
ADO.NET Entity Framework
23/10/2019 • 2 minutes to read • Edit Online
En esta sección se describen características y comportamientos específicos del proveedor de datos .NET
Framework para SQL Server (System.Data.SqlClient).
System.Data.SqlClient proporciona acceso a versiones de SQL Server, que encapsula los protocolos específicos de
base de datos. La funcionalidad del proveedor de datos se ha diseñado para que sea similar a la de los
proveedores de datos .NET Framework para OLE DB, ODBC y Oracle. System.Data.SqlClient incluye un analizador
de flujo TDS para comunicarse directamente con SQL Server.
NOTE
Para utilizar el proveedor de datos .NET Framework para SQL Server, la aplicación debe hacer referencia al espacio de
nombres System.Data.SqlClient.
Esta sección
Seguridad de SQL Server
Proporciona una introducción general a las características de seguridad de SQL Server y casos de creación de
aplicaciones ADO.NET seguras dirigidas a SQL Server.
Tipos de datos de SQL Server y ADO.NET
Describe cómo trabajar con tipos de datos de SQL Server y cómo interactúan con los tipos de datos de .NET
Framework.
Datos binarios y datos de valores grandes de SQL Server
Describe cómo trabajar con datos de valores grandes en SQL Server.
Operaciones de datos de SQL Server en ADO.NET
Describe cómo trabajar con datos XML en SQL Server. Contiene secciones acerca de operaciones de copia masiva,
MARS, operaciones asincrónicas y parámetros con valores de tabla.
Características de SQL Server y ADO.NET
Describe las características de SQL Server que resultan de utilidad para los desarrolladores de aplicaciones
ADO.NET.
LINQ to SQL
Describe los bloques de creación, procesos y técnicas básicos para crear aplicaciones LINQ to SQL.
Para obtener documentación completa del Motor de bases de datos de SQL Server, busque la versión de SQL
Server que utiliza en los Libros en pantalla de SQL Server.
Libros en pantalla de SQL Server
Vea también
Proteger aplicaciones de ADO.NET
Asignaciones de tipos de datos en ADO.NET
Objetos DataSet, DataTable y DataView
Recuperar y modificar datos en ADO.NET
Información general sobre ADO.NET
Objetos DataSet, DataTable y DataView
23/10/2019 • 5 minutes to read • Edit Online
El DataSet de ADO.NET es una representación de datos residente en memoria que proporciona un modelo de
programación relacional coherente independientemente del origen de datos que contiene. Un DataSet
representa un conjunto completo de datos, incluyendo las tablas que contienen, ordenan y restringen los datos,
así como las relaciones entre las tablas.
Hay varias maneras de trabajar con un DataSet, que se pueden aplicar de forma independiente o
conjuntamente. Puede:
Crear mediante programación una DataTable, DataRelation y una Constraint en un DataSet y rellenar las
tablas con datos.
Llenar el DataSet con tablas de datos de un origen de datos relacional existente mediante DataAdapter .
Cargar y hacer persistente el contenido de DataSet mediante XML. Para obtener más información, vea
Using XML in a DataSet (Usar XML en un conjunto de datos).
También se puede transportar un DataSet fuertemente tipado mediante un servicio Web XML. El diseño del
DataSet lo convierte en idóneo para el transporte de datos mediante servicios Web XML. Para obtener
información general sobre servicios Web XML, vea Información general de servicios Web XML. Para obtener un
ejemplo sobre cómo usar un objeto DataSet desde un servicio Web XML, vea Consuming a DataSet from an
XML Web Service (Usar un conjunto de datos desde un servicio Web XML).
En esta sección
Crear un objeto DataSet
Describe la sintaxis para crear una instancia de DataSet.
Agregar un objeto DataTable a un objeto DataSet
Describe cómo crear tablas y columnas y cómo agregarlas a un DataSet.
Agregar objetos DataRelation
Describe cómo se crean las relaciones entre tablas en un DataSet.
Navegar por objetos DataRelation
Describe cómo se utilizan las relaciones entre tablas en un DataSet para devolver la filas secundarias o
primarias de una relación primaria-secundaria.
Combinar contenido de DataSet
Describe cómo se fusiona mediante combinación el contenido de una matriz de DataSet, DataTable o DataRow
con otro DataSet.
Copiar el contenido de DataSet
Describe cómo se crea una copia de un DataSet que puede contener datos de esquema y datos especificados.
Controlar eventos de DataSet
Describe los eventos de un DataSet y cómo utilizarlos.
Objetos DataSet con tipo
Explica lo que es un DataSet con información de tipos y cómo crearlo y utilizarlo.
Objetos DataTable
Describe cómo se crea una DataTable, cómo se define el esquema y cómo se manipulan los datos.
Objetos DataTableReader
Describe cómo crear y utilizar un objeto DataTableReader.
Objetos DataView
Describe cómo se crean DataViews y cómo se trabaja con ellas, así como con eventos DataView.
Usar XML en un conjunto de datos
Describe cómo interactúa el DataSet con XML como origen de datos, incluyendo cómo cargar y hacer
persistente el contenido de un DataSet como datos XML.
Usar un conjunto de datos desde un servicio Web XML
Describe cómo crear un servicio Web XML que utilice un DataSet para transportar los datos.
Secciones relacionadas
Novedades de ADO.NET
Presenta características nuevas en ADO.NET.
Información general sobre ADO.NET
Proporciona una introducción al diseño y a los componentes de ADO.NET.
Rellenar un conjunto de datos desde un objeto DataAdapter
Describe cómo se carga un objeto DataSet con datos desde un origen de datos.
Actualizar orígenes de datos con objetos DataAdapter
Describe cómo se resuelven los cambios relacionados con los datos de un DataSet en el origen de datos.
Agregar restricciones existentes a un conjunto de datos
Describe cómo se rellena un objeto DataSet con información de clave principal de un origen de datos.
Vea también
ADO.NET
Información general sobre ADO.NET