ADO.NET

18/02/2005 - 10:59 por jsp | Informe spam
Hola,
Acabo de empezar con VB.NET y tengo una duda.
Tengo un Dataset enlazado a una tabla de SQL. Cuando modifico o inserto una
fila del dataset, para actualizar la tabla hay que hacer UPDATE(dataset). Si
antes haces AcceptChanges no me actualiza la tabla. No entiendo muy bien la
diferencia entre los dos. ¿donde puedo encontrar aclaracion a esto?
Vengo de VB6 y no encuentro el equivalente de MoveNext, MoveFirst..
¿con Find solo se puede buscar en campos clave? ¿Cual es el equivalente a
Find(Campo="busco") donde campo es cualquiera?
Un saludo y gracias por vuestra ayuda
Jesus

Preguntas similare

Leer las respuestas

#1 Tomas Martin
18/02/2005 - 13:42 | Informe spam
Hola Jesús, te respondo entre lineas:

Tengo un Dataset enlazado a una tabla de SQL. Cuando modifico o inserto


una
fila del dataset, para actualizar la tabla hay que hacer UPDATE(dataset).


Si
antes haces AcceptChanges no me actualiza la tabla. No entiendo muy bien


la
diferencia entre los dos. ¿donde puedo encontrar aclaracion a esto?



Un dataset guarda el estado de las filas que contiene (modificada, añadida,
borrada).
AcceptChanges deja dicho estado como si no se hubiese hecho ningún cambio en
el dataset desde su llenado por lo que si haces un Acceptchanges antes del
UpDate este no tendrá ningún efecto sobre la base de datos porque considera
que no hay ninguna modificación.
(Nota: DataAdapter.Update lleva implicito un AcceptChanges)

Vengo de VB6 y no encuentro el equivalente de MoveNext, MoveFirst..


Una Tabla no tiene conocimiento relativo a posición sobre las filas (es
similar a un array). Mira información sobre CurrencyManager.

¿con Find solo se puede buscar en campos clave?


Correcto si trabajas directamente sobre la tabla

¿Cual es el equivalente a Find(Campo="busco") donde campo es cualquiera?


Mira el método Find del DataView. Podrás buscar por el campo por el que esté
ordenado el DataView

Saludos

Tomás Martín
Respuesta Responder a este mensaje
#2 SqlRanger
18/02/2005 - 16:55 | Informe spam
Tomás,

Si bien en un dataview es fácil buscar por el campo que está ordenado,
también es posible buscar por cualquier otro, ya que DataView implementa LA
interfaz IBindingList que tiene el método Find( PropertyDescriptor,
KeyValue).

Aquí tienes una función que busca el primer registro cuyo valor de un
determinado campo sea igual a un valor dado. Devuelve el índice de ese
registro si lo encuentra y -1 si no lo encuentra. La pega de esta función es
que no sirve para encontrar todos los registros que cumplen la condición.

Public Function Buscar(ByVal dv As DataView, ByVal Campo As String,
ByVal Valor As Object) As Integer
Dim TypedList As ITypedList = dv
Dim BindingList As IBindingList = dv
Dim Descriptors As PropertyDescriptorCollection TypedList.GetItemProperties(Nothing)
Dim DescriptorCampo As PropertyDescriptor = Descriptors(Campo)
Return BindingList.Find(DescriptorCampo, Valor)
End Function



En ADO.NET en realidad no hay un equivalente del método find del recordset,
sobre todo cuando pones un criterio más complejo que un simple valor de un
campo. Los de Microsoft podrían haberlo hecho sin grandes dificultades, pero
lamentablemente no ha sido así. Sin embargo, recurriendo a Reflection es
posible crear una función que lo haga de forma eficiente.

Aquí tienes el método que busca en un dataview dado un criterio cualquiera y
te devuelve un array de enteros con los índices de las filas que cumplen la
condición. Ten encuenta que estos índices corresponden con la posición del
currencyManager, así que si tienes enlazado controles al dataview, al
establecer la posición del currency manager a uno de estos índices, los
controles enlazados mostrarán el registro correspondiente. Otra
característica de este método es que respeta el orden del dataview, es
decir, que si por ejemplo hubiera dos registros que cumplieran la condición,
el primer valor del array devuelto se encuentra primero en el orden del
dataview.

Esta función basa su búsqueda en el método Select del DataTable y encuentra
los índices (posición) de los registros del DataView usando el índice
interno del dataview que se guarda en el campo privado index. Este index es
un objeto de la clase System.Data.Index que es una clase Friend y que por
tanto no puedo acceder a ella sin la ayuda de reflection. Un objeto de la
clase System.Data.Index mantiene un mapeo entre los índices (posición) de
las filas del datatable y los correspondientes índices (posición) en el
dataview, o sea que si yo sé la posición que ocupa un DataRow en el
DataTable puedo saber qué posición ocupa el correspondiente DataRowView en
el DataView. El método GetIndex de System.Data.Index me da la posición del
DataRowView en el DataView correspondiente a un DataRow del DataTable
asociado. La posición del DataRow en el DataTable la obtengo del campo
privado rowID del DataRow:

Private Function Buscar(ByVal dv As DataView, ByVal Criterio As String)
As Integer()
Dim fiRowID As FieldInfo = GetType(DataRow).GetField("rowID",
BindingFlags.GetField Or BindingFlags.Instance Or BindingFlags.NonPublic)
Dim miGetIndex As MethodInfo Type.GetType("System.Data.Index,System.Data,Version=1.0.5000.0,Culture=Neutr
al,PublicKeyToken·7a5c561934e089").GetMethod("GetIndex")
Dim fiIndex As FieldInfo = GetType(DataView).GetField("index",
BindingFlags.GetField Or BindingFlags.Instance Or BindingFlags.NonPublic)

Dim Rows() As DataRow = dv.Table.Select(Criterio, dv.Sort,
dv.RowStateFilter)
If Rows.Length = 0 Then Return New Integer() {}
Dim Indices(Rows.Length - 1) As Integer
Dim DataViewIndex As Object = fiIndex.GetValue(dv)
Dim dvIndices(Rows.Length - 1) As Integer

For i As Integer = 0 To Rows.Length - 1
Dim rowIndex As Integer = fiRowID.GetValue(Rows(i)) - 1
Dim rvIndex As Integer = miGetIndex.Invoke(DataViewIndex, New
Object() {rowIndex})
dvIndices(i) = rvIndex
Next
Return dvIndices
End Function

Saludos:

Jesús López
MVP


"Tomas Martin" <t o m a s m m [ARROBA] m i c r o v e n [punto] n e t>
escribió en el mensaje news:
Hola Jesús, te respondo entre lineas:

> Tengo un Dataset enlazado a una tabla de SQL. Cuando modifico o inserto
una
> fila del dataset, para actualizar la tabla hay que hacer


UPDATE(dataset).
Si
> antes haces AcceptChanges no me actualiza la tabla. No entiendo muy bien
la
> diferencia entre los dos. ¿donde puedo encontrar aclaracion a esto?

Un dataset guarda el estado de las filas que contiene (modificada,


añadida,
borrada).
AcceptChanges deja dicho estado como si no se hubiese hecho ningún cambio


en
el dataset desde su llenado por lo que si haces un Acceptchanges antes del
UpDate este no tendrá ningún efecto sobre la base de datos porque


considera
que no hay ninguna modificación.
(Nota: DataAdapter.Update lleva implicito un AcceptChanges)

> Vengo de VB6 y no encuentro el equivalente de MoveNext, MoveFirst..
Una Tabla no tiene conocimiento relativo a posición sobre las filas (es
similar a un array). Mira información sobre CurrencyManager.

> ¿con Find solo se puede buscar en campos clave?
Correcto si trabajas directamente sobre la tabla

>¿Cual es el equivalente a Find(Campo="busco") donde campo es cualquiera?
Mira el método Find del DataView. Podrás buscar por el campo por el que


esté
ordenado el DataView

Saludos

Tomás Martín


Respuesta Responder a este mensaje
#3 Tomas Martin
18/02/2005 - 17:15 | Informe spam
Hola Jesús (López),
sólo puedo decir una cosa: Impresionante.
pero me temo que a Jesús (jsp) le vas a asustar ;-)

Un saludo
Tomás

PD: a ver si me llamas para solucionar 'eso' que tenemos pendiente

"SqlRanger" escribió en el mensaje
news:
Tomás,

Si bien en un dataview es fácil buscar por el campo que está ordenado,
también es posible buscar por cualquier otro, ya que DataView implementa


LA
interfaz IBindingList que tiene el método Find( PropertyDescriptor,
KeyValue).

Aquí tienes una función que busca el primer registro cuyo valor de un
determinado campo sea igual a un valor dado. Devuelve el índice de ese
registro si lo encuentra y -1 si no lo encuentra. La pega de esta función


es
que no sirve para encontrar todos los registros que cumplen la condición.

Public Function Buscar(ByVal dv As DataView, ByVal Campo As String,
ByVal Valor As Object) As Integer
Dim TypedList As ITypedList = dv
Dim BindingList As IBindingList = dv
Dim Descriptors As PropertyDescriptorCollection > TypedList.GetItemProperties(Nothing)
Dim DescriptorCampo As PropertyDescriptor = Descriptors(Campo)
Return BindingList.Find(DescriptorCampo, Valor)
End Function



En ADO.NET en realidad no hay un equivalente del método find del


recordset,
sobre todo cuando pones un criterio más complejo que un simple valor de un
campo. Los de Microsoft podrían haberlo hecho sin grandes dificultades,


pero
lamentablemente no ha sido así. Sin embargo, recurriendo a Reflection es
posible crear una función que lo haga de forma eficiente.

Aquí tienes el método que busca en un dataview dado un criterio cualquiera


y
te devuelve un array de enteros con los índices de las filas que cumplen


la
condición. Ten encuenta que estos índices corresponden con la posición


del
currencyManager, así que si tienes enlazado controles al dataview, al
establecer la posición del currency manager a uno de estos índices, los
controles enlazados mostrarán el registro correspondiente. Otra
característica de este método es que respeta el orden del dataview, es
decir, que si por ejemplo hubiera dos registros que cumplieran la


condición,
el primer valor del array devuelto se encuentra primero en el orden del
dataview.

Esta función basa su búsqueda en el método Select del DataTable y


encuentra
los índices (posición) de los registros del DataView usando el índice
interno del dataview que se guarda en el campo privado index. Este index


es
un objeto de la clase System.Data.Index que es una clase Friend y que por
tanto no puedo acceder a ella sin la ayuda de reflection. Un objeto de la
clase System.Data.Index mantiene un mapeo entre los índices (posición) de
las filas del datatable y los correspondientes índices (posición) en el
dataview, o sea que si yo sé la posición que ocupa un DataRow en el
DataTable puedo saber qué posición ocupa el correspondiente DataRowView en
el DataView. El método GetIndex de System.Data.Index me da la posición del
DataRowView en el DataView correspondiente a un DataRow del DataTable
asociado. La posición del DataRow en el DataTable la obtengo del campo
privado rowID del DataRow:

Private Function Buscar(ByVal dv As DataView, ByVal Criterio As


String)
As Integer()
Dim fiRowID As FieldInfo = GetType(DataRow).GetField("rowID",
BindingFlags.GetField Or BindingFlags.Instance Or BindingFlags.NonPublic)
Dim miGetIndex As MethodInfo >


Type.GetType("System.Data.Index,System.Data,Version=1.0.5000.0,Culture=Neutr
al,PublicKeyToken·7a5c561934e089").GetMethod("GetIndex")
Dim fiIndex As FieldInfo = GetType(DataView).GetField("index",
BindingFlags.GetField Or BindingFlags.Instance Or BindingFlags.NonPublic)

Dim Rows() As DataRow = dv.Table.Select(Criterio, dv.Sort,
dv.RowStateFilter)
If Rows.Length = 0 Then Return New Integer() {}
Dim Indices(Rows.Length - 1) As Integer
Dim DataViewIndex As Object = fiIndex.GetValue(dv)
Dim dvIndices(Rows.Length - 1) As Integer

For i As Integer = 0 To Rows.Length - 1
Dim rowIndex As Integer = fiRowID.GetValue(Rows(i)) - 1
Dim rvIndex As Integer = miGetIndex.Invoke(DataViewIndex, New
Object() {rowIndex})
dvIndices(i) = rvIndex
Next
Return dvIndices
End Function

Saludos:

Jesús López
MVP


"Tomas Martin" <t o m a s m m [ARROBA] m i c r o v e n [punto] n e t>
escribió en el mensaje news:
> Hola Jesús, te respondo entre lineas:
>
> > Tengo un Dataset enlazado a una tabla de SQL. Cuando modifico o


inserto
> una
> > fila del dataset, para actualizar la tabla hay que hacer
UPDATE(dataset).
> Si
> > antes haces AcceptChanges no me actualiza la tabla. No entiendo muy


bien
> la
> > diferencia entre los dos. ¿donde puedo encontrar aclaracion a esto?
>
> Un dataset guarda el estado de las filas que contiene (modificada,
añadida,
> borrada).
> AcceptChanges deja dicho estado como si no se hubiese hecho ningún


cambio
en
> el dataset desde su llenado por lo que si haces un Acceptchanges antes


del
> UpDate este no tendrá ningún efecto sobre la base de datos porque
considera
> que no hay ninguna modificación.
> (Nota: DataAdapter.Update lleva implicito un AcceptChanges)
>
> > Vengo de VB6 y no encuentro el equivalente de MoveNext, MoveFirst..
> Una Tabla no tiene conocimiento relativo a posición sobre las filas (es
> similar a un array). Mira información sobre CurrencyManager.
>
> > ¿con Find solo se puede buscar en campos clave?
> Correcto si trabajas directamente sobre la tabla
>
> >¿Cual es el equivalente a Find(Campo="busco") donde campo es


cualquiera?
> Mira el método Find del DataView. Podrás buscar por el campo por el que
esté
> ordenado el DataView
>
> Saludos
>
> Tomás Martín
>
>


Respuesta Responder a este mensaje
#4 Jesus
21/02/2005 - 11:41 | Informe spam
Muchas gracias a los dos. Me han resultado muy utiles vuestras explicaciones.
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida