Datagrid de 2 o más tablas

14/10/2005 - 10:06 por Sergi | Informe spam
Buenas!!

Estoy empezando a programar en visual basic .net y me estoy encontrando
con un problema repetidamente.

Por ejemplo, si tengo 3 tablas que fueran libros, clientes y compra. La
Tabla compra tendria un id de libros y clientes. Yo quiero un datagrid
donde muestre información de las 3 tablas, pero solo pueda modificar
la tabla compra.

Si creo una consulta con las tres tablas, no la puedo modificar sobre
el dataset, i si creo un dataset con 3 tablas, no puedo mostrar las 3
tablas en el datagrid.

Se tiene que controlar manualmente las modificaciones i los updates????
 

Leer las respuestas

#1 Jesús López
16/10/2005 - 10:29 | Informe spam
El problema es que cuando la instrucción Select incluye más de una tabla, el
asistente para el DataAdapter no es capaz de generar automáticamente los
comandos de actualización. Lo mismo le ocurre al CommandBuilder. La solución
es proporcionar tú mismo esos comandos de actualización al DataAdapter para
definir exáctamente como se revierten los cambios producidos en el datatable
sobre la base de datos. Al crear los comandos de actualización hay que poner
especial atención a las propiedades SourceColumn y SourceVersion de los
parámetros de los comandos ya que estas especifican el nombre de la columna
del datatable y versión de fila cuyo valor será copiado al parámetro antes
de ejecutar el comando.

En el caso que planteas, supongamos que estás usando SQL Server y que las
tablas son las siguientes:

create table Clientes
(
IdCliente int identity(1,1) primary key,
NombreCliente varchar(50) not null
)

go

create table Libros
(
IdLibro int identity(1,1) primary key,
Título varchar(50) not null
)

go

create table Compras
(
IdCompra int identity(1,1) primary key,
IdCliente int references Clientes(IdCliente),
IdLibro int references Libros(IdLibro),
Fecha DateTime
)

go

El método código siguiente incluye una propiedad AdapterCompras que servirá
para cargar los datos de las tres tablas combinadas por Joins y al mismo
tiempo servirá para guardar en la base de datos los cambios realizados en
esos datos, pero modificando sólo la tabla Compras. La propiedad
AdapterCompras sigue el patrón "lazy creation", es decir, que se crea sólo
cuando se necesita y sólo se creará una vez por muchas veces que se acceda a
ella:

Private cn As New SqlConnection("cadena de conexión")

Private mAdapterCompras As SqlDataAdapter

Public ReadOnly Property AdapterCompras() As SqlDataAdapter
Get
If mAdapterCompras Is Nothing Then
mAdapterCompras = CrearAdapterCompras(cn)
End If
Return mAdapterCompras
End Get
End Property

Private Function CrearAdapterCompras(ByVal cn As SqlConnection)
Dim Adapter As New SqlDataAdapter()

With Adapter
.SelectCommand = CrearSelectCommandCompras(cn)
.InsertCommand = CrearInsertCommandCompras(cn)
.DeleteCommand = CrearDeleteCommandCompras(cn)
.UpdateCommand = CrearUpdateCommandCompras(cn)
End With
Return Adapter

End Function

Private Function CrearSelectCommandCompras(ByVal cn As SqlConnection) As
SqlCommand

Dim SelectCommand As New SqlCommand("select NombreCliente, Título,
C.IdCompra, C.IdCliente, C.IdLibro, C.Fecha from Clientes CL join Compras C
On CL.IdCliente = C.IdCliente join Libros L ON C.IdLibro = L.IdLibro", cn)
Return SelectCommand
End Function

Private Function CrearInsertCommandCompras(ByVal cn As SqlConnection) As
SqlCommand
Dim InsertCommand As New SqlCommand("insert into Compras(IdCliente,
IdLibro, Fecha) values(@IdCliente, @IdLibro, @Fecha); select @@Identity As
IdCompra", cn)

Dim IdCliente As New SqlParameter("@IdCliente", SqlDbType.Int)
IdCliente.SourceColumn = "IdCliente"
IdCliente.SourceVersion = DataRowVersion.Current
InsertCommand.Parameters.Add(IdCliente)

Dim IdLibro As New SqlParameter("@IdLibro", SqlDbType.Int)
IdLibro.SourceColumn = "IdLibro"
IdLibro.SourceVersion = DataRowVersion.Current
InsertCommand.Parameters.Add(IdLibro)

Dim Fecha As New SqlParameter("@Fecha", SqlDbType.DateTime)
Fecha.SourceColumn = "Fecha"
Fecha.SourceVersion = DataRowVersion.Current
InsertCommand.Parameters.Add(Fecha)

Return InsertCommand

End Function

Private Function CrearDeleteCommandCompras(ByVal cn As SqlConnection) As
SqlCommand
Dim DeleteCommand As New SqlCommand("delete compras where IdCompra =
@IdCompra", cn)
Dim IdCompra As New SqlParameter("@IdCompra", SqlDbType.Int)
IdCompra.SourceColumn = "IdCompra"
IdCompra.SourceVersion = DataRowVersion.Original
DeleteCommand.Parameters.Add(IdCompra)
Return DeleteCommand
End Function

Private Function CrearUpdateCommandCompras(ByVal cn As SqlConnection) As
SqlCommand
Dim UpdateCommand As New SqlCommand("update compras set IdLibro =
@IdLibro, IdCliente = @IdCliente, Fecha = @Fecha where IdCompra =
@IdCompra", cn)
Dim IdCliente As New SqlParameter("@IdCliente", SqlDbType.Int)
IdCliente.SourceColumn = "IdCliente"
IdCliente.SourceVersion = DataRowVersion.Current
UpdateCommand.Parameters.Add(IdCliente)

Dim IdLibro As New SqlParameter("@IdLibro", SqlDbType.Int)
IdLibro.SourceColumn = "IdLibro"
IdLibro.SourceVersion = DataRowVersion.Current
UpdateCommand.Parameters.Add(IdLibro)

Dim Fecha As New SqlParameter("@Fecha", SqlDbType.DateTime)
Fecha.SourceColumn = "Fecha"
Fecha.SourceVersion = DataRowVersion.Current
UpdateCommand.Parameters.Add(Fecha)

Dim IdCompra As New SqlParameter("@IdCompra", SqlDbType.Int)
IdCompra.SourceColumn = "IdCompra"
IdCompra.SourceVersion = DataRowVersion.Original
UpdateCommand.Parameters.Add(IdCompra)

Return UpdateCommand


End Function


Generalmente los nombres de las columnas en el datatable coinciden con los
nombres de los parámetros de los comandos, aunque esto no tiene por qué ser
siempres así. En este ejemplo los nombres de las columnas coinciden con los
nombres de los parámetros.

En un delete command, la propiedad SourceVersion de los parámetros debe ser
siempre DataRowVersion.Original ya que una fila eliminada en un datatable no
tiene versión actual.
En un insert command, la propiedad SourceVersion de los parámetros debe ser
siempre DataRowVesion.Current ya que una fila nueva en un datatable no tiene
versión original.
En un update command, la propiedad SourceVersion de los parámteros puede ser
tanto Orginal, como Current. Los parámetros que corresponden a la parte SET
del update, deberán tener la propiedad SourceVersion =
DataRowVersion.Current y los que corresponden a la cláusula WHERE deberán
tener la propiedad SourceVersion = DataRowVesion.Original.

En este ejemplo he escrito todo el código necesario para crear el
dataadapter, el select command y los comandos de actualización. Sin embargo
es posible ayudarse del diseñador de Visual Studio para realizar esta tarea.
Lo cual es lo más recomendable ya que te ayuda a hacerlo más rápidamente y
cometer menos errores.

Para el dataadpater, podemos arrastrarlo de la caja de herramientas sobre el
componente o formulario en vista diseño y lo configuramos con el asistente.
Le proporcionamos la instrucción select y listo. Veremos que los comandos de
actualización no podrán ser generados, eso no nos preocupará ya que lo
haremos más tarde:

Añadimos, por cada comando de actualización y SqlCommand a la superficie de
diseño arrastrándolo de la caja de heramientas y configuramos sus
propiedades y parámtros ayudándonos de la ventana de propiedades:

(1) Le asignamos la conexión
(2) Establecemos la propiedad CommandText ayudándonos del Diseñador de
consultas
(3) Configuramos la coleccción de parámetros

Una vez configurados los comandos de actualización los asignamos a las
propiedades UpdateCommand, InsertCommand y DeleteCommand del DataAdapter
usando la ventana de propiedades.






"Sergi" escribió en el mensaje
news:
Buenas!!

Estoy empezando a programar en visual basic .net y me estoy encontrando
con un problema repetidamente.

Por ejemplo, si tengo 3 tablas que fueran libros, clientes y compra. La
Tabla compra tendria un id de libros y clientes. Yo quiero un datagrid
donde muestre información de las 3 tablas, pero solo pueda modificar
la tabla compra.

Si creo una consulta con las tres tablas, no la puedo modificar sobre
el dataset, i si creo un dataset con 3 tablas, no puedo mostrar las 3
tablas en el datagrid.

Se tiene que controlar manualmente las modificaciones i los updates????

Preguntas similares