L'indice di riga è la posizione di un determinato Record in un resulset e chi proviene da ADO , ha notato sicuramente che la differenza tra ADO.NET e quest'ultimo è sicuramente notevole.
Uno dei problemi che potreste incontrare durante le vostre prime prove è la mancanza di un metodo per recuperare l'indice di riga data una particolare chiave di ricerca.
Un metodo Find lo ritroviamo nell'oggetto DataTable e cj restituisce una matrice di DataRows , ma non la posizione della prima occorrenza utile a soddisfare la ricerca.
Quando ci si scontra con alcuni progetti che richiedono ancora tale funzione bisogna trovare metodi alternativ. In questo articolo vedremo come ottenere l'indice di riga da due oggetti fondamentali in ADO.NET che sono il DataTable e il DataView.
Cercare l'occorrenza
Ecco allora un esempio: immaginate di dover mostrare sempre tutti i record di una tabella e paginarli in una DataGrid , poi di dover effettuare una ricerca su questa tabella e mostrare non solo i record paginati, ma posizionarsi anche sulla prima occorrenza della nostra ricerca.
Nell'esempio che segue, visualizziamo tutti i CompanyName della tabella Customers del DataBase Northwind.
A questo punto inseriamo nella casella di testo la stringa Paris ed osserviamo il risultato.
Come si può notare nell'immagine non si è estratto solo i record che hanno soddisfatto i nostri criteri, ma la ricerca si è indirizzata nella pagina dove ha trovato la prima occorrenza utile a soddisfare la ricerca stessa.
Ecco il codice necessario per arrivare a questa funzionalità:
Private Sub Binding() Dim StrCon As String = "Initial Catalog=Northwind;Data Source=localhost;Integrated Security=SSPI;" Dim SqlStr As String = "SELECT CompanyName FROM Customers" Dim Cnn As New SqlConnection(StrCon) Dim Ds As New DataTable Dim Da As New SqlDataAdapter(SqlStr, Cnn) Dim dt As New DataTable 'Try Da.Fill(dt) If TextBox1.Text <> "" Then If RadioButton1.Checked Then'Ricerca con DataTable Nriga = Find(dt) Else'Ricerca con la Vista Nriga = Find(dt.DefaultView) End If If Nriga > 0 Then Dim Position As Int32 If Nriga Mod GridResult.PageSize = 0 Then Position = (Nriga \ GridResult.PageSize) - 1 Else Position = (Nriga \ GridResult.PageSize) End If GridResult.CurrentPageIndex = Position End If End If GridResult.DataSource = dt GridResult.DataBind() End Sub
La funzione Binding estrae tutti i dati, mentresolo la funzione Find ci permette di ottenere l'indice di riga per la nostra ricerca.
Tale funzione non fa altro che applicare il metodo Find , nel caso di un DataTable, o RowFilter , nel caso di un DataView, per effettuare la ricerca, come fareste normalmente.
Per ottenere l'indice dobbiamo far uso della classe Reflection per andare a vedere il campo rowID che valore ha assunto.
RowID è infatti un campo non pubblico di una DataRow e contiene di fatto l'indice di riga, ovvero la posizione che ha all'interno di un oggetto DataTable o DataView. Vediamo come fare:
Private Function Find(ByVal Dt As DataTable) As Int32<br /> Dim Righe() As DataRow = Dt.Select("CompanyName Like'" & TextBox1.Text.Replace("'", "''") & "%'")<br /> If Righe.Length > 0 Then<br /> Dim rowFieldsInfo As FieldInfo = GetType(DataRow).GetField("rowID", BindingFlags.NonPublic Or BindingFlags.Instance)<br /> Dim rowId As Int32 = Convert.ToInt32(rowFieldsInfo.GetValue(Righe(0)))<br /> Return rowId<br /> End If<br /> End Function<br /> <br /> Private Function Find(ByVal DV As DataView) As Int32<br /> DV.RowFilter = "CompanyName Like'" & TextBox1.Text.Replace("'", "''") & "%'"<br /> If DV.Count > 0 Then<br /> <br /> Dim Riga As DataRowView = DV.Item(0) 'recupero la prima riga<br /> ' Converto DataRowView in una DataRow<br /> Dim rowFieldsInfo As FieldInfo = GetType(DataRowView).GetField("row", BindingFlags.NonPublic Or BindingFlags.Instance)<br /> Dim NuovaRiga As DataRow = CType(rowFieldsInfo.GetValue(Riga), DataRow)<br /> <br /> Dim rowFieldsInfo2 As FieldInfo = GetType(DataRow).GetField("rowID", BindingFlags.NonPublic Or BindingFlags.Instance)<br /> Dim rowId As Int32 = Convert.ToInt32(rowFieldsInfo2.GetValue(NuovaRiga))<br /> DV.RowFilter = ""<br /> Return rowId<br /> End If<br /> DV.RowFilter = ""<br /> End Function
L'overload di tale funzione è data dal fatto che il percorso per ottenere l'indice di riga in un oggetto DataView è un pò più articolato, perchè bisogna di fatto ottenere un oggetto DataRow da un oggetto DataRowView, il quale non espone nessun membro pubblico per tale oggetto.
Conclusioni
Anche se molto semplice, l'articolo di oggi, sfruttando due caratteristiche del .NET Framework, come la reflection e l'uso di collection per contene i dati, ci ha mostrato un tipico utilizzo di vecchie caratteristiche, disponibili con ADO, all'interno delle nuove funzionalità offerte da ADO.NET.
Approfondimenti
- Introduzione ad ADO.NET
- I Data Controls DataList e Repeater
- Tutti gli script dedicati ad ADO.NET
- Tutti gli script dedicati al DataGrid
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.