• No results found

Productive versus difference-making causation

Chapter 2: Kim’s causal exclusion argument against non-reductivism

2.5 A hidden premise in the exclusion argument

2.5.3 Productive versus difference-making causation

El procesamiento de datos ha dependido, principalmente, de un modelo basado en una conexión. A medida que el procesamiento de datos utiliza cada vez más arquitecturas de varios niveles, los programadores están pasando a un enfoque sin conexión. Existen dos componentes de ADO.NET que se pueden utilizar para obtener acceso a datos:

Proveedores de datos de .NET Framework: permite manipular los datos y

acceso de sólo lectura.

DataSet: permite el acceso a datos independientemente del origen de datos.

En este capítulo estudiaremos al DataSet y su Modelo.

2 DATASET

El DataSet es una representación de datos residente en memoria que proporciona un modelo de programación relacional coherente con independencia del origen de datos. Representa un conjunto completo de datos que incluye tablas relacionadas y restricciones, así como relaciones entre las tablas. En la siguiente ilustración, se muestra el modelo de objetos DataSet.

2.1 Creación de un DataSet

Al crear un DataSet se define una instancia de Dataset llamando a su constructor. Si lo desea, especifique un nombre de argumento. Si no especifica ninguno, se le asignará "NewDataSet".

También puede crearse un nuevo DataSet basado en un DataSet existente. El método Clone solo copia la estructura del DataSet original. El método GetChanges solo copiará los datos modificados. Si ejecuta el método Copy, copia el contenido del DataSet.

Dim ds As New DataSet("DsFactura")

2.2 Forma de añadir una tabla a DataSet

ADO .NET te habilita para crear objetos DataTables y añadirlos a un

DataSet existente. El siguiente ejemplo define un DataSet y se añade un

DataTable al DataSet.

2.3 Forma de añadir columnas a una tabla

El esquema de una tabla está representado por columnas y constraints. La definición de un esquema de un DataTable es a través de los objetos

DataColumn, como también de los objetos ForeignKeyConstraint y UniqueConstraint.

Se crea un objeto DataColumn dentro de una DataTable utilizando un constructor de DataColumn o llamando al método Add de la propiedad

Columns de una tabla. El método Add aceptará:

o ColumnName: nombre de la columna.

o DataType: tipo de dato de la columna.

o Expresión: argumento que crea una nueva columna.

En el siguiente ejemplo, se añade 4 columnas a la tabla Recibos.

o también a través del DataColumn.

2.4 Creación de expresiones

Puede definirse una expresión para una columna, habilitándolo para contener un valor calculado desde otra columna en la misma fila o desde valores de varias columnas de las filas en la tabla. El DataType debe ser el apropiado para el valor de la expresión.

En el siguiente ejemplo, agregar la columna renta que representa el 10% del monto.

Dim ds As New DataSet("DsFactura") Dim tabla As New DataTable("Clientes") ds.Tables.Add(tabla)

Dim tabla As New DataTable("Recibos")

tabla.Columns.Add("numero", Type.GetType("System.String")) tabla.Columns.Add("fecha", Type.GetType("System.DateTime")) tabla.Columns.Add("detalle", Type.GetType("System.String")) tabla.Columns.Add("monto", Type.GetType("System.Decimal")))

Dim tabla As New DataTable("Recibos")

Dim dc As New DataColumn("num", Type.GetType("System.String")) tabla.Columns.Add(dc)

dc = New DataColumn("fecha", Type.GetType("System.DateTime")) tabla.Columns.Add(dc)

dc = New DataColumn("detalle", Type.GetType("System.String")) tabla.Columns.Add(dc)

dc = New DataColumn("monto", Type.GetType("System.Decimal")) tabla.Columns.Add(dc)

tabla.Columns.Add("monto", Type.GetType("System.Decimal")) tabla.Columns.Add("monto", Type.GetType("System.Decimal"), _

86 86 86 86

o se puede generar a través del DataColumn.

2.5 Creación de columnas que generen autogeneren valores

Para asegurar que los valores sean únicos, puede colocar una columna cuyos valores se incrementen automáticamente cuando se añade una nueva columna. Para crear una columna Autoincrementada, colocar la propiedad AutoIncrement a true. A continuación, se define las siguientes propiedades:

Opción Descripción

AutoIncrementSeed Valor inicial del autogenerado

AutoIncrementStep Valor incremental

ReadOnly Indica que la columna será de solo lectura

En el siguiente ejemplo agregar la columna número, cuyo valor se incrementará de 5 en 5, a partir del valor de 10.

2.6 Definición de una clave primaria para la tabla

Una tabla, por lo general, tiene una columna o un grupo de columnas que identifica en forma única a cada fila dentro de la tabla. La identificación es llamada Primary key. Cuando un dataColumn se identifica como

PrimaryKey para la tabla, la propiedad AllowDBNull es falsa, pero la

propiedad Unique no es colocada a true.

La propiedad PrimaryKey recibe los valores como un array de una o más objetos DataColumns. El siguiente ejemplo permite definir un Primary Key de una columna o un Primary Key de dos columnas.

dc = New DataColumn("monto", Type.GetType("System.Decimal")) tabla.Columns.Add(dc)

dc = New DataColumn("monto", Type.GetType("System.Decimal")) dc.Expression = "monto*0.10"

tabla.Columns.Add(dc)

Dc= New DataColumn("numero", Type.GetType("System.Int32")) dc.AutoIncrement = True

dc.AutoIncrementSeed = 10 dc.AutoIncrementStep = 5 dc.ReadOnly = True

tabla.Columns.Add(dc)

tabla.PrimaryKey = New DataColumn() {tabla.Columns(0)} 'o

dc = tabla.Columns(0)

tabla.PrimaryKey = New DataColumn() {dc}

tabla.PrimaryKey = New DataColumn() {tabla.Columns(0), tabla.Columns(1)}

2.6 Forma de añadir un Constraint a una tabla

Puede utilizar Constraint para establecer restricciones a los datos en un

DataTable y mantener la integridad de datos. Un Constraint es una regla,

aplicada a una columna que determina el curso de acción cuando el valor de una fila es alterada. Existen dos tipos de constraint: ForeignKeyConstraint y el UniqueConstraint.

2.6.1 ForeignKeyConstraint

Las propiedades DeleteRule y UpdateRule definen la acción a ser tomada cuando el usuario actualiza o elimina una fila en la tabla relacionada. Si una fila de la tabla principal es eliminada, también se borrarán los registros de la tabla hija que tienen el mismo valor.

A continuación, se muestra las reglas para las propiedades de

UpdateRule y DeleteRule.

Rule Descripción

Cascade Elimina o actualiza las filas relacionadas.

SetNull Coloca el valor relacional a DBNull.

SetDefault Coloca el valor por defecto a las filas relacionales.

None Especifica que no se efectúa acción a las filas relacionales. El objeto ForeignKeyConstraint es agregado a la colección Constraint de la tabla relacionada a través del método Add.

El siguiente ejemplo establece un ForeignKey entre las tablas clientes y factura, donde el valor DeleteRule es None.

2.6.2 UniqueConstraint

El objeto UniqueConstraint aplica la unicidad de los valores de las filas de una tabla para una columna o un array de columnas. Se puede crear un UniqueConstraint para una columna o array de columnas.

El objeto UniqueConstraint es agregado a la colección Constraint de la tabla a través del método Add.

Podemos crear una constraint de tipo Unique asignando la propiedad

Unique a true.

El siguiente ejemplo permite crear UniqueConstraint a la columna num.

Dim FKCliFact As New ForeignKeyConstraint("FK1", _

Cliente.Columns("cli_codigo"), Factura.Columns("cli_codigo")) FKCliFact.DeleteRule = Rule.None

dataSet.Tables("Factura").Constraints.Add(FKCliFact)

Dim dc As New DataColumn("num", Type.GetType("System.Int32")) dc.Unique = True

88 88 88 88

El siguiente ejemplo permite crear UniqueConstraint, a dos columnas.

2.7 FORMA DE AÑADIR RELACIONES ENTRE TABLAS

En un DataSet que contiene muchas tablas (DataTables), puede utilizar objetos DataRelations donde, permita relacionar dos tablas, navegar entre los registros de las dos tablas y retorne los registros de la tabla hija.

Para crear un DataRelation, se debe establecer como argumentos el campo de la tabla padre y el campo de la tabla referencial o hija.

Añadiendo un DataRelation a un DataSet, por defecto se crea un Constraint de tipo Unique en la tabla padre y otro constraint de tipo Foreign en la tabla hija, para recuperar todas las filas de facturas de una fila de clientes determinada mediante GetChildRows.

El siguiente ejemplo crea una relación de la tabla clientes y facturas donde la primera columna será de la tabla padre (clientes) y la segunda será de la tabla hija (facturas).

3 DATAADAPTER

El DataSet es un conjunto de datos que residen en memoria, el cual nos proporciona un modelo relacional independiente del origen de datos.

Como el DataSet es independiente al origen de datos, para interactuar con los orígenes de datos actuales se necesita del DataAdapter.

Un DataAdapter es usado para recuperar los datos desde un origen de datos y publica tablas dentro de un DataSet. Los proveedores que incluye para el

DataAdapter son:

Proveedor Descripción

SqlDataAdapter Proveedor para SQL Server

OleDbDataAdapter Proveedor para OLE DB

OdbcDataAdapter Proveedor para ODBC

OracleDataAdapter Proveedor para Oracle Dim uknumeros As New UniqueConstraint( _

New DataColumn() {ds.Tables("facturas").Columns(0), _ ds.Tables("facturas").Columns(1)})

ds.Tables("facturas").Constraints.Add(uknumeros)

Dim relclifac As New DataRelation( _

"r1", ds.Tables("clientes").Columns(“cli_codigo”), ds.Tables("facturas").Columns(“cli_codigo”))

ds.Relations.Add(relclifac)

For Each pRow In ds.Tables("Clientes").Rows

Console.WriteLine(pRow("cli_codigo").ToString()) For Each cRow In pRow.GetChildRows(relation)

Console.WriteLine(vbTab & cRow("fac_numero").ToString()) Next

3.1 CONFIGURACIÓN DE UN DATAADAPTER

El DataAdapter tiene 4 propiedades que son utilizadas para recibir y actualizar datos al origen de datos:

Propiedades Descripción

InsertCommand Comando para insertar filas en un almacén de datos.

UpdateCommand Comando para modificar filas en el almacén de datos.

DeleteCommand Comando para eliminar filas en el almacén de datos.

SelectCommand Comando para recuperar filas en el almacén de datos.

En el ejercicio ejecutamos una consulta (Select) en la tabla facturas y procedemos a poblar los registros al DataSet utilizando el método Fill.

3.2 MÉTODO PARA POBLAR LOS DATOS DESDE UN DATAADAPTER

El método Fill del DataAdapter es usado para poblar un DataSet con los resultados del SelectCommand del DataAdapter. El Método Fill toma como argumentos el nombre del DataSet para publicar los registros y el nombre del objeto DataTable.

3.2.1 Llenar un DataSet desde múltiples DataAdapter

Se puede utilizar cualquier cantidad de objetos DataAdapter con un

DataSet. Cada DataAdapter se puede utilizar para llenar uno o varios

objetos DataTable y para reflejar en el origen de datos correspondiente las actualizaciones que sean necesarias. Se pueden agregar, de forma local, objetos DataRelation y Constraint al DataSet, de manera que se pueden relacionar datos procedentes de varios orígenes distintos. Para ocuparse de la comunicación con cada origen de datos se pueden usar uno o varios objetos DataAdapter.

Dim da As New SqlDataAdapter("Select * from Facturas", cn) Dim ds As New DataSet

da.Fill(ds, "facturas")

Dim daCli As New SqlDataAdapter("SELECT * FROM Clientes", cn) Dim daFact As New SqlDataAdapter("SELECT * FROM Facturas", cn) Dim ds As New DataSet()

daCli.Fill(ds, "Clientes") daFact.Fill(ds, "Facturas")

Dim relation As DataRelation = ds.Relations.Add("CustOrders", _ ds.Tables("Clientes").Columns("cli_codigo"), _

ds.Tables("Facturas").Columns("cli_codigo")) Dim pRow, cRow As DataRow

For Each pRow In ds.Tables("Clientes").Rows

Console.WriteLine(pRow("cli_codigo").ToString()) For Each cRow In pRow.GetChildRows(relation)

Console.WriteLine(vbTab & cRow("fac_numero").ToString()) Next

90 90 90 90

3.3 ACTUALIZANDO UNA BASE DE DATOS CON UN DATAADAPTER Y UN DATASET

El método Update del DataAdapter efectúa los cambios efectuados en un

DataSet. El método Update, al igual que el método Fill, acepta como

argumentos una instancia de un DataSet el que contiene los cambios efectuados y un objeto DataTable que identifica la tabla desde la que se pueden recuperar esos cambios.

Al llamar al método Update, el DataAdapter analiza los cambios efectuados y ejecuta el comando apropiado (INSERT, UPDATE o DELETE). Cuando el

DataAdapter encuentra un cambio en una DataRow, utiliza los comandos InsertCommand, UpdateCommand o DeleteCommand para reflejarlo. Antes

de llamar a Update, debe establecer de forma explícita los comandos.

El método Update refleja, en el origen de datos los cambios efectuados, pero ya han modificado datos en el origen de datos desde el momento en que se llenó el DataSet. Utilice el DataAdapter y el método Fill.

Si el método Fill encuentra un valor de clave principal para una fila del 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 del DataSet, el método Fill agrega una nueva fila con un RowState de Unchanged.

En este ejemplo, se demuestra cómo se deben realizar las actualizaciones en las filas modificadas estableciendo, de forma explícita, el comando UpdateCommand de DataAdapter. Observe cómo el parámetro @cod especificado en la cláusula WHERE de la instrucción UPDATE utiliza 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. Dim da As New SqlDataAdapter("Select * from Articulos", cn)

da.UpdateCommand = New SqlCommand("Update Articulos Set art_nombre=@nom, art_precio=@pre, art_stock = @st Where art_codigo=@cod", cn)

With da.UpdateCommand.Parameters

.Add("@nom", SqlDbType.VarChar, 30, "art_nombre") .Add("@pre", SqlDbType.Decimal, 10, "art_precio") .Add("@st", SqlDbType.Int, 10, "art_stock")

Dim par As SqlParameter = .Add("@cod", SqlDbType.Char) par.SourceColumn = "art_codigo"

par.SourceVersion = DataRowVersion.Original End With

Dim ds As New DataSet da.Fill(ds, "Articulos")

Dim row As DataRow = ds1.Tables("Articulos").Rows(i) row("art_stock") = Val(txtstock.Text)

row("art_nombre") = Me.txtdescripcion.Text row("art_precio") = Val(Me.txtprecio.Text) da.Update(ds, "Articulos")