Ado net (versione 1 e 2)
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Ado net (versione 1 e 2)

on

  • 1,565 views

 

Statistics

Views

Total Views
1,565
Views on SlideShare
1,565
Embed Views
0

Actions

Likes
0
Downloads
17
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Ado net (versione 1 e 2) Presentation Transcript

  • 1. Microsoft ADO.NET ActiveX Data Object .NETIng. Felice Pescatorefelice.pescatore@poste.it
  • 2. ADO.NET: Compendi Consigliati Autori: • msdn2.microsoft.com/it-it/library/default.aspx •Francesco Balena • www.ugidotnet.org •Dino Esposito • www.aspitalia.com •Marco Bellinaso • www.dotnet2themax.it •David Sheppa
  • 3. ADO.NET: introduzioneADO.NET è il componente per laccesso ai dati del Microsoft .NET Framework.Si tratta di una evoluzione del precedente componente ADO con cui ha pochi punti in comune e rappresenta una vera e propria rivoluzione per svariati motivi che andremo ad analizzare.ADO.NET è formato da una collezione di classi, interfacce, strutture etipi,che gestiscono l‟accesso ai dati all‟interno del .NET framework, di cuisono parte integrante, e sono organizzate in namespace a partire daSystem.Data.
  • 4. ADO.NET: ado.net vs. ado (1) Caratteristiche salienti di ADO  Architettura Connessa;  Legato al modello fisico dei dati;  RecordSet è il “contenitore” finale dei dati ricavati;  RecordSet è in pratica una tabella contenete tutti i dati:  Per ottenere dati da più tabelle è necessario effettuare un JOIN;  I Dati ottenuti sono “piatti”, sono perse le relazioni ed è possibile consultarli solo in modo sequenziale;  I dati sono converti nei corrispettivi formati COM/COM+ ;  I dati vengono scambiati attraverso COM-marshalling  Non sempre il formato binario di rappresentazione dei dati (DCOM, binary) riesce a superare i firewall.
  • 5. ADO.NET: ado.net vs. ado (2) Caratteristiche salienti di ADO.NET  Progettato per Accesso Disconnesso  Modello di dati organizzato logicamente  Il DataSet sostituisce il RecordSet  DataSet può contenere più tabelle  Ottenere dati da più tabelle non richiede un JOIN;  Le relazioni tra le tabelle sono preservate così come relazionale è la modalità di accesso ai dati;  I tipi di dati sono mappati attraverso un XML schema;  Nessuna conversione dei tati richiesti  XML, come HTML, è puro testo e permette di passare agevolmente i firewall;
  • 6. ADO.NET: ado.net vs. ado (3) XxxConnection Connection XxxTransaction ADO.NET Command XxxCommand ADO DataSet Recordset XxxDataReader XxxDataAdapter XXX sarà sosituito dal prefisso relativo all‟RDBMS scelta. Ad esempio nel caso di SQL Server si avranno: SQLConnection, SQLTransaction, ecc.
  • 7. ADO.NET: architettura connessa vs architettura disconnessa La nuova architettura XxxDataReader Disconnessa di ADO.NET DataSet consente di recuperare i dati dalla relativa fonte e crarne una rappresentazione in memoria su cui XxxCommand effettuare le elaborazioni, una sorta XxxDataAdapter di cache-database contenuto nel RecordSet. Questo permette di effettuare tutte le operazioni senza XxxConnection XxxConnection essere connessi direttamente alla fonte dati e, successivamente, inviare gli aggiornamenti Data Data
  • 8. ADO.NET: architettura applicativa
  • 9. ADO.NET: vantaggi Alta Interoperabilità grazie all‟uso di XML:  Standard aperti per i dati che si autodescrivono  Informazioni facilmente leggibili  Uso interno della mappatura ma utilizzabile esternamente, per poter leggere, scrivere e sostituire i dati; Elevata Scalabilità grazie all‟uso dei DataSet disconnessi:  Le connessioni sono mantenute solo per brevi periodi  Non è necessario effettuare il lock del database (comunque supportato attraverso i ServiceComponents e comunque in modalità ottimistica-Optimistic);  Modalità pensata per lavorare secondo il paradigma delle web application; Manutenibilità  Separazione tra i dati e la loro rappresentazione
  • 10. ADO.NET: architetturaCome tutti gli altri componenti del .NET Framework, ADO.NET consiste di un insieme di oggetti che interagiscono fra loro per svolgere una determinata funzione (è appunto un framework). ADO.NET è composto da due componenti fondamentali: • il Data (Managed) Provider che mantiene la connessione con la sorgente dati fisica; • il DataSet (e più in generale i Data Storage), che rappresenta i dati attuali, ovvero i dati su cui si sta lavorando. .NET Data Provider Data Consumer .NET Data Storage Connection DataSet WinForm Command DataTables WebForm DataAdapter XMLData DataReader XMLDataSchema Altri XML Entrambi i componenti possono Data Source comunicare con i Data Consumers , ovvero i fruitori dei loro servizi, come, ad esempio una WinForm o una WebForm.
  • 11. ADO.NET: architettura .NET Application DataSetSystem.Data.Oracle System.Data.SqlClient System.Data.OleDb System.Data.Odbc OLE DB OLE DB Provider ODBC Non-relational Oracle SQL Server Other DBMS sources
  • 12. ADO.NET: Data ProviderAttraverso il Data Provider è possibile ottenere/inviare dati da/a un qualsiasi tipodi sorgente dati: •Relazionale •XML •CustomOgni sorgente dati ha un proprio Data Provider ed ognuno di essi espone gli stessimetodi (implementando le stesse interfacce o classi base) di base con opportuniprefissi specifici.Il Data Provider comprende vari tipi di oggetti: • xxxConnection: rappresenta la connessione fisica con la sorgente dati • xxxCommand: rappresenta un comando da eseguire sulla sorgente dati (ad es. un’istruzione SQL) • xxxDataReader: permette di ottenere in modo veloce, read-only e forward-only i dati dalla sorgente dati • xxxDataAdapter fornisce il meccanismo di interazione tra la connessione e il data set
  • 13. ADO.NET: SQL Data Provider Object Model SqlConnection SqlCommand System.Xml.XmlReader SqlDataReader SqlParameterCollection Object SqlParameter Common Language Runtime SQL CLIENT TDS SQL PARSER SERVER
  • 14. ADO.NET: OleDB Data Provider Object Model OleDbConnection .CreateCommand .ExecuteReader OleDbCommand .Connection .Parameters OleDbDataReader OleDbParameterCollection .Add .Item .CreateParameter .Item Object OleDbParameter Common Language Runtime OleDb Provider OLEDB Data Source Managed Relazionale Provider e non
  • 15. ADO.NET: ODBC Data Provider Object Model OdbcConnection .CreateCommand .ExecuteReader OdbcCommand .Connection .Parameters OdbcDataReader OdbcParameterCollection .Add .Item .CreateParameter .Item Object OdbcParameter Common Language Runtime ODBC DRIVER ODBC Managed Data Source Relazionale Provider
  • 16. ADO.NET: DB2 Data Provider L‟accesso a DB2 di IBM può avvenire attraverso i provider OleDb o ODBC illustrati prima oppure attraverso uno specifico managed provider sviluppato da IBM Application Application Application System.Data.OleDb Microsft.Data.ODBC IBM.Data.DB2 OLE DB .Net ODBC .Net DB2 .Net Data Data Provider Data Provider Provider OleDbConnection OdbcConnection DB2Connection OleDbCommand OdbcCommand DB2Command OleDbAdapter OdbcDataAdapter DB2DataAdapter OleDbDataReader OdbcDataReader DB2DataReader IBM DB2 OLE IBM DB2 DB Provider ODBC Driver DB2
  • 17. ADO.NET: Oracle Data Provider Nel caso di Oracle si ha uno scenario ulteriormente diverso con 2 provider specifici: • Microsoft .NET Data Provider per Oracle, prodotto da Microsoft e usa gli strumenti client di Oracle • Oracle Data Provider per .NET (ODP.NET), sviluppato da Oracle, presenta un‟ integrazione completa esponendo tutte le caratteristiche di un Oracle DB In pù è disponibile l‟Oracle Connect per .NET per l‟uso con OleDB e Odbc
  • 18. ADO.NET: Data Provider, Classe Connection La classe Connection (simile a quella presente in ADO classico) implementa l‟interfaccia IDBConnection; Per poter effettuare la connessione bisogna specificare una Connection String, che:  Può essere specificata mediante un costruttore parametrico;  Utilizza le stesse keyword di ADODB; [Visual Basic] Dim conSQL As SqlConnection = New SqlConnection("Data Source=localhost;Integrated” & _ Security=SSPI;Initial Catalog=northwind") SqlConnection.Open() [C#] SqlConnection SqlConnection = new SqlConnection("Data Source=localhost; Integrated Security=SSPI; Initial Catalog=northwind"); SqlConnection.Open();
  • 19. ADO.NET: Data Provider, Classe Command Una volta creata una connessione è possibile fare una interrogazione alla sorgente dati e ottenerne una rappresentazione in memoria. Per realizzare ciò si fa ricorso alla classe Command che implementa l‟interfaccia IDBCommand In base al risultato atteso è possiamo eseguire un comando attraverso metodi specificatamente ottimizzati: • ExecuteReader() • da utilizzare quando è previsto un result set (DataReader) come ritorno; • ExecuteScalar() • da utilizzare per aggregazioni o risultati di calcoli; • ritorna solo la prima colonna della prima riga, gli altri dati vengono persi; • ExecuteNonQuery() • ottimizzato per query che non ritornano result set ma solo parametri di ritorno o numero di record modificati; • ExecuteXMLReader() • specifico per l‟accesso a dati di tipo XML; Le prime tre versioni di Execute vanno usate adeguatamente in modo da garantire performance ottimali nelle proprie applicazioni.
  • 20. ADO.NET: Data Provider, Classe Command e Query libere Dim sqlConn As SQLConnection Dim sqlCmd As SQLCommandVediamo un Dim rowsAffected As Integer esempio Try completo di Creo la connessione utilizzo della sqlConn = New SQLConnection(myConnString) classe Creo il comando Command. sqlCmd = New SQLCommand() specifico il tipo di comandoUn oggetto With sqlCmd Command può .CommandType = CommandType.Text essere creato in .CommandText = "Insert Customers (Alias, CustomerName) _ Values (myAlias,myName)" due modi: .Connection = sqlConn • Mediante il End With costruttore; apro la connessione • Mediante il sqlConn.Open() metodo eseguo il comando, vengono ritornate le righe inserite CreateCom rowsAffected = sqlCmd.ExecuteNonQuery() mand da Catch e As Exception inocare gestisco l‟eccezione … sull’oggetto Finally connessione chiudo la connesione sqlConn.Close() End Try
  • 21. ADO.NET: Data Provider, Classe Command & Stored Procedure Attraverso la classe Command è possibile invocare una StoredProcedure (se la sorgete dati le preveda). Per fare ciò bisogna: • Creare un oggetto Command; • Impostare CommandType al valore StoredProcedure; • Impostare la proprietà CommandText; • Usare il metodo Add per creare e aggiungere parametri; • Impostare la proprietà ParameterDirection; • Invocare ExecuteReader; • Consumare i record, e chiudere il DataReader; • Leggere i parametri di output e il valore di ritorno. Nel caso in cui sia necessario impostare a NULL un paramero di input è possibile utilizzare DBNull.Value.
  • 22. ADO.NET: Data Provider, Classe Command & Stored Procedure sqlConn = New SQLConnection(myConnString) Creo il Command sqlCmd = New SQLCommand() Specifico la Stored Procedure e la connessione With sqlCmd .CommandType = CommandType.StoredProcedure .CommandText = "InsertCustomer" .Connection = sqlConn End With Definisco e aggiung un parametro alla relativa collection param = sqlCmd.Parameters.Add(New SQLParameter("@p", SQLDBType.NVarChar, 100) With param .Direction = ParameterDirection.Input Setto il valore del parametro .Value = “xyz" End With Aggiungo i parametri rimanenti … Apro la connessione sqlConn.Open() Eseguo il comando rowsAffected = sqlCmd.ExecuteNonQuery()
  • 23. ADO.NET: Data Provider, Classe DataReader Come accennato un DataReader permette di ottenere in modo veloce, read- only e forward-only i dati dalla sorgente. Si tratta in pratica del duale del Recordset di ADO. La classe DataReader implementa le interfacce IDataReader e IDataRecord Attraverso il DataReader è possibile: • Avanzare alla posizione successiva mediante il metodo Read(), che ritorna True finchè non si sono consumati tutti i dati; • Accedere ai dati nelle singole colonne per indice o per nome del campo; • Accedere ai dati attraverso metodo accessori dedicati ai tipi di dato contenuti: GetDateTime(), GetDouble(), GetGuid(), GetInt32()
  • 24. ADO.NET: Data Provider, Classe DataReader[Visual Basic]Dim myReader As SqlDataReader = myCommand.ExecuteReader()Do While myReader.Read() Console.WriteLine(vbTab & "{0}" & vbTab & "{1}", myReader.GetInt32(0),myReader.GetString(1))LoopmyReader.Close()[C#]SqlDataReader myReader = myCommand.ExecuteReader();while (myReader.Read()) Console.WriteLine("t{0}t{1}", myReader.GetInt32(0), myReader.GetString(1));myReader.Close();E‟ importante sottolineare che un DataReader impegna la propria connessione, quindi: • Non è possibile utilizzarla per eseguire comandi; • Dobbiamo ricordarci di chiuderlo mediante il metodo Close();
  • 25. ADO.NET: Data Provider, Classe XmlReaderVediamo come utilizzare l’ExecuteXmlReader() per ottenere un XmlReader:[Visual Basic]Dim custCMD As SqlCommand = New SqlCommand("SELECT * FROM Customers FOR XML_ AUTO, ELEMENTS", nwindConn)Dim myXR As System.Xml.XmlReader = custCMD.ExecuteXmlReader()[C#]SqlCommand custCMD = new SqlCommand("SELECT * FROM Customers FOR XML AUTO,ELEMENTS", nwindConn);System.Xml.XmlReader myXR = custCMD.ExecuteXmlReader();
  • 26. ADO.NET: Data Provider, TransazioniLe Transizioni sono utilizzate per rendere atomiche una serie di operazioni su un insieme di dati, in modo che vengano realizzate tutte o nessuna. [VB.NET]Le Transizioni Locali sono OleDbConnection conn = new OleDbConnection();l‟equivalente imperativo di quelle conn.Open("...");native SQL OleDbTransaction tx = conn.BeginTransaction();(BEGIN/COMMINT TRAN) OleDbCommand cmd = conn.CreateCommand();contenute,ad esempio, cmd.CommandText = "...";nelle Stored Procedure. cmd.Transaction = tx; cmd.ExecuteNonQuery();Vediamo con un esempio pratico tx.Commit();come realizzare una transizionecon Ado.Net: [C#] SqlConnection conn = new SqlConnection(); conn.Open("..."); SqlTransaction tx = conn.BeginTransaction(); SqlCommand cmd = conn.CreateCommand(); cmd.CommandText = "..."; cmd.Transaction = tx; cmd.ExecuteNonQuery(); tx.Commit();
  • 27. ADO.NET: Data Provider, ExceptionEventuali errori durante l‟esecuzione di operazioni sulla fonte dati vengonointercettati attraverso le eccezioni.Ogni Managed providers implementa le proprie eccezioni derivanti da •SqlException •SqlErrorL‟evento di base da gestire per cattuare le eccezioni è InfoMessage, gestibileattraverso il delegato SqlInfoMessageEventHandler public static void myHandler(object conn, SqlInfoMessageEventArgs e) Metodo da { passare al delegato Console.WriteLine("caught a SQL warning"); for (int i=0; i < e.Errors.Count; i++) { Console.WriteLine("Index#" + i + "n" + "Warning:" + e.Errors[i].ToString() + "n"); } }
  • 28. ADO.NET: Data Provider, Exceptionpublic static int Main(string[] args) {try Gestione { delle SqlConnection conn = new SqlConnection(“ConnectionString”); eccezioni // Associo un event handler all‟evento di InfoMessage conn.InfoMessage += new SqlInfoMessageEventHandler(myHandler); conn.Open(); } catch (SqlException e) { for (int i=0; i < e.Errors.Count; i++) { Console.WriteLine("Index #" + i + "n Error: " + e.Errors[i].ToString() + "n"); }catch (Exception e) { Console.WriteLine(e.Message); }finally { conn.Close(); } return 0; }
  • 29. ADO.NET: Data Set Fin qui si potrebbe obiettare che tutto sommato le cose sono come in ADO, fatta eccezione per denominazione diversa di oggetti e metodi e la gestione delle eccezioni. Vero, ma ora parliamo dei Data Set che sono il fulcro del disconnected work.
  • 30. ADO.NET: Data SetPermette di gestire i dati come se si disponesse di database relazionaleimmagazzinato nella memoria del processo.Le caratteristiche salienti di un Data Set sono: • Residente in memoria di lavoro; • Disconnesso dalla sorgente dati esterna; • Permette di specificare vincoli e relazioni tra i dati contenuti; • E‟ accessibile in scrittura; • Permette di propagare le modifiche alla sorgente dati; • Supporta nativamente la (de)serializzazione in formato XML • E‟ un contenitore di vari tipi di oggetti (in particolare tabelle e relative relazioni): o DataTable – rappresenta una tabella o DataColumn – rappresenta una colonna di una tabella o DataRow – rappresenta una riga di una tabella o Constraint – rappresenta un vincolo di integrità su una tabella o DataRelation – rappresenta una relazione tra due tabelle
  • 31. ADO.NET: Data Set Object Model Collezioni DataSet DataSet DataRelationsCollection DataTableCollection DataRelation DataTable DataTable DataTable ConstraintCollection DataRowCollection DataColumnCollectionDataColumn DataRow Constraint DataRow DataColumn
  • 32. ADO.NET: Ruolo del DataAdapter Select xxxCommand xxxCommandBuilder xxxDataAdapter Insert xxxCommand xxxConnection Update xxxCommand Delete xxxCommand Data DataSet
  • 33. ADO.NET: Architettura del DataAdapter XxxDataAdapter SelectCommand UpdateCommand InsertCommand DeleteCommand XxxDataReader XxxCommand XxxCommand XxxCommand XxxCommand XxxConnection sp_SELECT sp_UPDATE sp_INSERT sp_DELETE
  • 34. ADO.NET: Popolare un Data SetEssendo un Data Set una sorta di mini-db relazionale in memoria è possibilepopolarlo si accedendo ad una sorgente dati come un RDBMS: Dim adaptSQL As New SqlClient.SqlDataAdapter(“Select * from authors", conSQL) Dim datPubs As DataSet = New DataSet( ) adaptSQL.Fill(datPubs, "NewTable")ma anche creandolo per via programmatica Dim datPubs As New DataSet( ) Dim tblAuthors As DataTable = New DataTable("authors") tblAuthors.Columns.Add("AuthorID", System.Type.GetType("System.Int32"))Nel primo caso (quello più consueto) spicca la creazione della classeSqlDataAdapter che è il vero nodo di collegamento tra il “mondo” connesso equello disconnesso. Infatti il DataSet viene “riempito” dai dati e si può lavorarein modalità disconessa.Terminate le attività di modifica è possibile aggiornare la sorgente dati originale: adaptSQL.Update (datPubs, "miaTabella")
  • 35. ADO.NET: la proprietà DataRowSetOgni riga inserita nella rispettiva tabella ha uno stato contenuto della proprietàRowState del DataRow. In pratica una riga modifica il proprio stato dopo ognimodifica.I valori che il RowState può assumere sono contenuti nell‟enumeratoreDataRowState: Valore Descrizione Added La riga è stata aggiunta alla tabella Deleted La riga è contrassegnata per l’eliminazione della tabella Detached La riga è stata creata ma non ancora aggiunta alla tabella o è stata eliminata dalla collection delle righe Modified Alcune colonne della riga sono state modificate Unchanged Nessuna modifca è stata eseguita dall’ultima invocazione a AcceptChanges. E’ anche lo stato di tutte le righe quando la tabella viene creata II metodo AcceptChanges conferma le modifiche e porta lo stato in unchanged. Lo stesso vale per la RejectChanges che però annulla le modifiche
  • 36. ADO.NET: Data Set multi TabellaCome esposto la potenza di un DataSet è quello di contenere più tabelle e lerelative relazioni.Vediamo come inserire più tabelle in un DataSet grazie al metodo FILL():Dim mySqlDataAdapter As New SqlDataAdapter("select * from customers", mySqlConnection)Dim myDataSet As New DataSet()mySqlDataAdapter.Fill(myDataSet, "Customers") Tabella CustomersmySqlDataAdapter.SelectCommand.CommandText = "select * from orders"mySqlDataAdapter.Fill(myDataSet,"Orders") Tabella Orders DataSet: Customers Orders Data Tables
  • 37. ADO.NET: Data Set, classe DataTableOgni elemento della proprietà Tables è un‟istanza della classe DataTableUn oggetto DataTable espone le proprietà: • Columns: è una collezione di istanze di DataColumn • Rows: è una collezione di istanze della classe DataRow • Una istanza della classe DataRow: mette a disposizione il contenuto delle proprie colonne mediante la proprietà Item Vediamo un utilizzo di tali proprietà: Dim numeroRighe As Int32 = unaTabella.Rows.Count Dim indiceRiga As Int32 Dim unaRiga As DataRow For indiceRiga = 0 To numeroRighe - 1 unaRiga = unaTabella.Rows(indiceRiga) Dim nomeAutore As String = _ unaRiga.Item("au_fname").ToString() Next
  • 38. ADO.NET: Data Set, classe DataRelationOltre alla proprietà tables, fondamentale è Relations, una collezione di istanzedella classe DataRelation.Un oggetto DataRelation espone le proprietà: • definisce una associazione tra le colonne di differenti DataTable; • definisce una associazione orientata alla navigazione sui dati; • NON costituisce una constraint; Vediamo un utilizzo di tali proprietà patendo dalla loro creazione: Dim relPubsTitle As New DataRelation("PubsTitles", _ datPubs.Tables("Publishers").Columns("pub_id"), _ datPubs.Tables("Titles").Columns("pub_id")) datPubs.Relations.Add(relPubsTitle) Accedere ai dati associati Dim PubRow, TitleRow As DataRow, TitleRows( ) As DataRow PubRow = datPubs.Tables("Publishers").Rows(0) TitleRows = PubRow.GetChildRows("PubsTitles")
  • 39. ADO.NET: Data Set, usare Constraint Il supporto alle constraint della classe DataSet permette di: • Creare constraint attraverso le classi ForeignKeyConstraints e UniqueConstraints • Usare le constraint esistenti nel DB adaptSQL = New SqlClient.SqlDataAdapter("Select title_id title, type, price from titles", conSQL) adaptSQL.FillSchema(datPubs, schematype.Source, "Titles") adaptSQL.Fill(datPubs, "Titles") Operazioni sui dati adaptSQL.Fill(datPubs, "Titles") Una constraint ForeignKeyConstraint:  permette l‟integrità referenziale se la proprietà EnforceConstraints del DataSet è impostata a True  Determina le azioni effettuate nelle tabelle correlate, attraverso le proprietà DeleteRule e UpdateRule Azione Descrizione Cascade Cancella o aggiorna le righe correlate. E’ il default. SetNull Imposta a DBNull il valore delle righe correlate. SetDefault Imposta al DefaultValue il valore delle righe correlate. None Nessuna azione/modifica, viene sollevata una eccezione.
  • 40. ADO.NET: Data Set, modificare i dati Vediamo come elaborare i dati attraverso i DataSet. Aggiungere Righe Dim drNewRow As DataRow = datPubs.Tables("Titles").NewRow Popolare le colonne datPubs.Tables("Titles").Rows.Add(drNewRow) Modificare Righe drChangeRow.BeginEdit( ) drChangeRow("Title") = drChangeRow("Title").ToString & " 1" drChangeRow.EndEdit( ) Cancellare Righe datPubs.Tables("Titles").Rows.Remove(drDelRow)
  • 41. ADO.NET: Data Set, aggiornare la sorgente dati Possiamo ripercuotere le modifiche effettuate al DataSet sul DB: Esplicitando il comando di aggiornamento Dim comm As New SqlClient.SqlCommand("Insert titles" & _ "(title_id, title, type) values(@t_id,@title,@type)") comm.Parameters.Add("@t_id",SqlDbType.VarChar,6,"title_id") comm.Parameters.Add("@title",SqlDbType.VarChar,80,"title") comm.Parameters.Add("@type",SqlDbType.Char,12,"type") adaptSQL.InsertCommand = comm adaptSQL.Update(datPubs, "titles") Generando automaticamente il comando di update Dim sqlCommBuild As New SqlCommandBuilder(adaptSQL) MsgBox(sqlCommBuild.GetInsertCommand.CommandText) adaptSQL.Update(datPubs, "titles")
  • 42. Microsoft: ADO.NET 1.x to 2.0 ActiveX Data Object .NET dalla versione 1.x alla 2.0
  • 43. ADO.NET 2.0: evoluzione ADO.NET v1.0/1.1 è basato su alcune interfacce comuni, implementate dai singoli provider. Nonostante la flessibilità che ciò comporta è problematico scrivere codice indipendente dalla base dati. ADO .NET 2.0 è basato su classi base condivise dai provider, e si presenta come un‟estensione delle versioni precedenti non non introducendo alcuna incompatibilità. L‟utilizzo di classi base condivise e non di interfacce permette di implementare un‟architettura basata sul pattern Factory. Resta comunque la presenza di una sintassi SQL è specifica per la base dati; Architettura basata sul pattern Factory.
  • 44. ADO.NET 2.0: Common Provider Model IDb* interfaces (es: IDbConnection) Layer Db* abstract base classes (es: DbConnection) Provider-Independent Db*Base implementation classes 3rd 3rd Layer Sql OleDb ODBC Oracle Party 1 Party 2 Provider-SpecificADO.NET 2 usa un set di classi base che espongono i metodi necessari a generare: Connection, Commands, Parameters, ecc.In pratica viene inserito un nuovo layer (provider indipendent) che va a posizionarsi tra leclassiche interfacce IDB* e la relativa implementazione specifica. Il motivo dell‟introduzione ditale layer (e delle relative classi base) sarà chiaro a breve.E‟ utile precisare che lo sviluppatore può continuare ad usare, se lo desidera, le vecchie tecnicheesistenti nelle precedenti versioni senza alcuna modifica.
  • 45. ADO.NET 2.0: Classi Provider Indipendent Le nuove classi base sono definite nel namespace System.Data.Commamd Di seguito elenchiamo le più comuni: DbCommand DbCommandBuilder DbConnection DataAdapter DbDataAdapter DbDataReader DbParameter DbParameterCollection DbTransaction DbProviderFactory DbProviderFactories DbException
  • 46. ADO.NET 2.0: insieme dei componenti DataSource TableAdapter TableAdapter TableAdapter DataTable DataTable DataTable DataSet BindingSource BindingSource BindingSource NamedRange ListObject Label Bookmark TextBox Label
  • 47. ADO.NET 2.0: il Pattern FactoryIl Pattern Factory (classificato come Creational Pattern) ha lo scopo di creare facilmentenuovi oggetti, in dipendenza degli eventuali parametri passati al metodo di creazione.Creazione normale di un oggetto: Creazione con il Factory Class1 myClass = new Class1() Class1 myClass = Factory.create()
  • 48. ADO.NET 2.0: il Pattern Factory in Ado.net 2 Il Ado.Net 2 il pattern Factory è implementato nel namespace System.Data.Common Come si usa: 1. Importare il namespace System.Dta.Common 2. Creare l‟istanza del Factory: DbProviderFactory factory = DbProviderFactories.GetFactory("provider-name") 3. Creare le instanze degli oggetti: DbConnection con = factory.CreateConnection() DbCommand cmd = con.CreateCommand() Come si può intuire la dinamicità sta nel parametro passato al metodo GetFactory. Infatti è possible utilizzare variare la sorgente dati utilizza semplicemente variando il relativo parametro e lasciando tutti il resto del codice inalterato!
  • 49. ADO.NET 2.0: Provider EnumeratorDove recuperiamo i nomi dei managed provider disponibili?Assodato che ogni provider ha un nome invariante per esempio: "System.Data.SqlClient", "System.Data.OracleClient"è possibile ottenerne la lista dei provider factory disponibili attraverso il metodo: GetFactoryClasses() il quale ritorna un oggetto di tipo DataTable. DataTable dt = DbProviderFactories.GetFactoryClasses() DbProviderFactory factory = DbProviderFactories.GetFactory(dt.Rows[x]) ... o ... DbProviderFactory factory = DbProviderFactories.GetFactory( dt.Select("InvariantName=System.Data.SqlClient") [0]["InvariantName"].ToString());
  • 50. ADO.NET 2.0: Performance ImprovementsNella versione 1.x Ado.Net offriva ottime performance per l‟inserimento di datiall‟interno dei DataSet, ma gli aggiornamenti soffrivano del numero di righe presential suo interno.La versione 2.0 introduce una indicizzazione interna delle righe per ottimizzare leprestazioni. Infatti i tempi di: • Insert e Delete crescono logaritmicamente (tempi necessari all‟aggiornamento degli indici); •Update rimangono quasi costanti (grazie all‟accesso delle righe tramite gli indici)Con la versione 2.0 fa la comparsa anche la Serializzazione binaria dei DataSet.Infatti i DataSet v1.x erano sempre serializzati in XML, vantaggioso per lo scambiodati, ma penalizzante per le performance.La v2.0 supporta la serializzazione binaria che è più veloce ed occupa meno spazioa scapito ovviamente dell‟interoperabilità. Per ottenere tale serializzazione bastaimpostare la proprietà RemotingFormat del DataSet DataSet.RemotingFormat = SerializationFormat.Binary
  • 51. ADO.NET 2.0: Popolare un Data Set (1)Esistono varie modalità per popolare un Data Set: • da un datasource (DataSet o DataTable), utilizzando il DataAdapter ed il metodo Fill: DataAdapter.Fill(DataSet, "table-name") con la versione 2 questo metodo ha guadagnato due nuove proprietà: • DataAdapter.FillLoadOption • AcceptChangesDuringUpdate • effettuando il Merge delle righe da un altro DataSet attraverso il metodo Merge • caricando i dati attraverso un DataReader tramite il nuovo metodo DataSet.Load: Load(DataReader [, load-option] [, tables-array]) utilizzando l‟enumeratore LoadOption: • PreserveCurrentValues • UpdateCurrentValues • OverwriteRow
  • 52. ADO.NET 2.0: Popolare un Data Set (2)Compariamo le tre tecniche viste nella slide precedente: • DataAdapter.Fill(): popola il DataSet con una tabella alla volta. Dopo l‟inserimento di ogni riga viene invocato automaticamente l‟AcceptChanges; se si desidera modificare tale comportament bisogna settare la proprietà AcceptChangesDuringFill. Il metodo Fill() può anche essere utilizzato per effettuare il refresh delle tuple: infatti se si caricano righe con primary key già presenti del DataSet, quest‟ultime verranno sostituite. • DataSet.Merge(): permette combinare le righe di due DataSet diversi. Le righe del DataSet di lettura vengono inserite nelle tabelle (con lo steso nome) del primo, sostituendo eventualmente quelle con lo stesso primary key. Nel caso si voglia un comportamento diverso bisogna settare il parametro PreserveChange. Al termine delle operazioni lo stato delle righe è Modified o Added. • DataSet.Load(): è il nuovo metodo introdotto con Ado.Net 2. Attraverso un DataReader è possibile utilizzare una query che ritorna più tabelle che vengono inserite nel DataSet usando il nome specificato dal parametro table-array. Per catturare eventuali errori è possibile specificare un delegato che effettui le opportune operazioni.Sia il metodo Fill() che il metodo Load() traggono vantaggio dal nuovo enumeratoreLoadOption. Nel caso di Fill() è utilizzato settando il parametro FillLoadOption delDataAdapter, mentre nel caso di Load() come parametro. In pratica grazie a LoadOption èpossibile controllare il modo in cui le righe vengono unite (merge) tra loro.
  • 53. ADO.NET 2.0: Popolare un Data Set (3) RowState of PreserveCurrentValues UpdateCurrentValues OverwriteRow Existing Row (the default value)Added Current = Existing Current = Incoming Current = Incoming Original = Incoming Original = Existing Original = Incoming RowState = Modified RowState = Added RowState = UnchangedModified Current = Existing Current = Incoming Current = Incoming Original = Incoming Original = Existing Original = Incoming RowState = Modified RowState = Modified RowState = UnchangedDeleted Current = Existing * Undo Delete * Undo Delete Original = Incoming Current = Incoming Current = Incoming RowState = Deleted Original = Existing Original = Incoming RowState = Modified RowState = UnchangedUnchanged Current = Incoming Current = Incoming Current = Incoming Original = Incoming Original = Existing Original = Incoming RowState = Unchanged * if new value = existing RowState = Unchanged value: RowState = Unchanged * else: RowState = ModifiedNo matching Current = Incoming Current = Incoming Current = Incomingexisting row in Original = Incoming Original = Existing Original = Incomingthe table RowState = Unchanged RowState = Added RowState = Unchanged
  • 54. ADO.NET 2.0: Altre nuove feauturesAdo.Net 1.x non prevedeva la possibilità di settare manualmente lo stato delle righe:lo stato era aggiornato automaticamente in base alle operazione effettuate. Questopoteva rendere difficile l‟aggiornamento di specifiche righe perché l‟Update non eracondizionabile.Ado.Net 2 introduce due metodi relativi ai DataRow: •DataRow.SetAdded •DataRow.SetModifiedproprio per variarne lo stato.Ado.Net 2 introduce inoltre la classe DataTableReader in grado di convertire i daticontenuti in un DataSet in uno stream, utile per passare un DataSet ad una claseche accetta un DataReaeder. Va evidenziato che è possibile specificare quali tabelleesportare.Per ottenere un DataTableReadere è possibile invocare DataSet.GetDataReader().
  • 55. ADO.NET 2.0: Altre nuove feauturesAdo.Net 2 ha reso indipendente il DataTable. Praticamente è possibile effettuare con essotutte le operazioni previste per il DataSet: ReadXml, ReadXmlSchema, WriteXml, WriteXmlSchema, Clear, Clone, Copy, Merge, GetChangessupportando direttamente la serializzazione (implementando l‟interfaccia IXmlSerializable) epermettendo quindi di restituirne un‟istanza mediante WebServices o Remoting.Capite bene che inviare su rete un singolo DataTable è molto più conveniente che un interoDataSet!Ovviamente per essere totalmente indipendente deve essere possibile popolare direttamenteun DataTable. Ecco quindi il motivo dell‟implementazione dei metodi del DataAdapter chesupportino direttamente un DataTable: •DataAdapter.Fill(DataTable) •DataAdapter.Fill(DataTable[ ], …) •DataAdapter.Update(DataTable)e dei metodi propri del DataTable: •DataTable.Load(DataReader [, load-option] [, FillErrorEventHandler]) •DataTable.GetDataReader, ottiene uno stream da una DataTable
  • 56. ADO.NET 2.0: Comandi AsincroniADO.NET 2 introduce il modello di esecuzione asincrona (similare all‟APM delframework .net 2) che riduce i tempi di latenza delle web/windows aplpicationdurante le operazioni sui dati, permettendo l‟esecuzione concorrente di moltepliciquery.Seguendo proprio l’APM Model i metodi sono del tipo: BeginXXX ed EndXXX, adesempio: • BeginExecuteReader e EndExecuteReader; • BeginExecuteNonQuery e EndExecuteNonQuerycosì è possibile utilizzare le tecniche di Polling, Wait e Callback per eseguireoperazioni in attesa del completamento del metodo BeginXXX.Per poter utilizzare il modello asincrono bisogna aggiungere "async=true" allaConnection String ed evitare di utilzzare i Multiple Active Results Sets (di cuiparleremo dopo).
  • 57. ADO.NET 2.0: Esecuzione Asincrona Application Rowset 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Database1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Connection Latency 3 secs Data 1 Data 1 Data 1 Data 1 Rowset 2 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Database2 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Connection Latency 8 secs Data 1 Data 1 Data 1 Data 1 Rowset 3 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Database3 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Connection Latency 5 secs Data 1 Data 1 Data 1 Data 1 Tempo per visualizzare i dati: ~ 3 secs 16 11 secsNel caso di esecuzione sincrona, ogni connection deve attendere il termine dellaprecedente per poter ritornare i dati e quindi per permette all‟applicazione divisualizzarli.Risultato: il tempo totale è la somma (teorica) dei tempi necessari alle tre connection
  • 58. ADO.NET 2.0: Esecuzione Asincrona Application Rowset 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Database1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Connection1 Latency 3 secs Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Rowset 2 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Database2 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Connection2 Latency 8 secs Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Rowset 3 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Database3 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Connection3 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Data 1 Latency 5 secs Data 1 Data 1 Data 1 Data 1 ~ 8 secsNel caso di esecuzione asincrona, le connection vengono avviatecontemporaneamente e ritorna appena terminano la propria attività, indipendementedalle altre (nell‟esempio la terza connection ritorna dopo 5sec invece che dei 16precedenti).Risultato: il tempo totale è pari al tempo della connection più lenta.
  • 59. ADO.NET 2.0: Design Approaches (1)In attesa del completamento di un comando di BeginXXX possiamo effettuare altreoperazioni utilizzando tre tecniche: Polling, Wait (All & Any) e Callback.Polling Model • Avviare il comando asincrono: Dim result As IAsyncResult = MyCommand.BeginExecuteReader() •Aspettare fino al termine dell‟escuzione: While Not result.IsCompleted „Codice da eseguire End While •Recupera i Risultati Dim reader As SqlDataReader = MyCommand.EndExecuteReader(result ) nel caso di query che non ritorna un rowset (BeginExecuteNonQuery, BeginExecuteScalar, etc.) è possibile ottenere il numero di righe interessate dall‟operazione o un singolo valore.
  • 60. ADO.NET 2.0: Design Approaches (2)Wait (All) Model • Avviare uno o più comandi asincroni: Dim resultx As IAsyncResult = MyCommand.BeginExecuteReader() • Attendere il completamento di tutti i comandi WaitHandle.WaitAll(New WaitHandle() {result1.AsyncWaitHandle, result2.AsyncWaitHandle, result3.AsyncWaitHandle}, timeout - ms, True) •Recupera i Risultati Dim reader As SqlDataReader = MyCommand.EndExecuteReader(resultx)Questo modello è ideale per le applicazioni ASP.NET (dove è necessario avere tutti idati prima di poter fare qualcosa) ed analogomante per generare l‟output da un WebServices.
  • 61. ADO.NET 2.0: Design Approaches (3)Wait (Any) Model • Avviare uno o più comandi asincroni come array di istanze di IAsyncResult: Dim resultx As IAsyncResult = MyCommand.BeginExecuteReader() • Attendere il completamento di ogni comando i comandi Dim i As Integer For i = 0 To result_array.Length index = WaitHandle.WaitAny(result_array, timeout, true) Select Case index Case 0 Dim reader As SqlDataReader = MyCommand.EndExecuteReader(resultx) .... End Select End For per catturare eventuali timeout, il Case deve contenere una clausola “case WaitHandle.WaitTimeout”Questo modello è ideale per le Windows Application perché permette di visualizzare(utilizzare) i dati appena diventano disponibili senza aspettare il risultato di tutte lequery. Inoltre grazie al metodo Load del DataSet è possibile usare immediatamenteogni singolo dataReader per caricare una tabella nel DataSet stesso.
  • 62. ADO.NET 2.0: Design Approaches (4)Callback Model • Avviare l‟esecuzione, specificando la funzione di callback (delegato) ed il Command come AsyncState: MyCommand.BeginExecuteReader(new AsyncCallback(MyCallback), cmd) • Creare il gestore di callback Sub MyCallback(ByVal result As IAsyncResult) Dim cmd As SqlCommand = DirectCast(result.AsyncState, SqlCommand) Dim reader As SqlDataReader = cmd.EndExecuteReader(result) End SubSi tratta probabilmente dell‟approccio migliore perché lascia al runtime la gestionecompleta della chiamata asincrona e l‟incovazione auomatica di un metodo cheesegua le opportune operazioni su dati ottenuti.Il tutto mentre l‟applicativo continua la sua “normale” esecuzione.
  • 63. ADO.NET 2.0: Design Approaches (5)Per ognuno degli approcci presentati bisogna applicare una gestione apposita delleEccezioni e dei TimeOut. •Per il WaitOne e WaitAll è preferibile usare sempre il try/catch per ogni metodo EndXXX •Per il WaitAny il return value è uguale al tempo di TimeOut •Per il CallBack è preferibile usare sempre il try/catch per ogni metodo EndXXX
  • 64. ADO.NET 2.0: Multiple Active Results Sets (MARS) (1) (Ri)Conoscete questo messaggio?  “System.InvalidOperationException: There is already an open DataReader associated with this Connection which must be closed first.”In ADO.NET 1.x provando ad aprire più results set o effettuare più “update”query su una Connection provoca la suddetta eccezione.In ADO.NET 2 (con le Connection relative a SQL Server 2005) è possibile inveceaprire più results set sulla stessa Connection ed eseguire comandi multipli dimodifica sui datiIn sintesi: • Mantiene disponibile una connessione quando apriamo un SqlDataReader al fine di poter: • Eseguire un‟altra query per ottenere un DataReader/XmlReader • Eseguire comandi DML • Possono essere attivi differenti result set contemporaeamente • alternare fetch ad ogni reader • Alternare query che non restituiscono reader
  • 65. ADO.NET 2.0: Multiple Active Results Sets (MARS) (2) Vediamo uno scenario tipo: • Recuperare la lista dei clienti e scorrerla • Per ogni cliente, recuperare la lista degli ordini • Per ogni ordine, recuperarne il dettaglio Nella v.1.x di Ado.Net, per ottenere ciò usando dei reader erano necessarie differenti connessioni Mediante MARS, è sufficiente una sola connessione se: • I dati risiedono nello stesso database • Usiamo SQL Server 2005/MDAC9 E‟ utile evidenziare che MARS è solo una feuture che semplifica le attività di sviluppo, occupandosi automaticamente di gestire aperture/connessione delle connection necessario. Quindi va usato con attenzione per evitare cali prestazionali della propria applicazione.
  • 66. ADO.NET 2.0: Multiple Active Results Sets (MARS) (3) Vediamo un esempio: Dim parentReader As DataReader = Command1.ExecuteReader() While parentReader.Read() processa la tupla letta crea il childReader Command2.Parameters("@id").Value = parentReader("id") Dim childReader As DataReader = Command2.ExecuteReader() processa il nuovo childReader childReader.Close() End While parentReader.Close() Questo codice apre un DataReader (parentReder) e chiama ciclicamente la Read() finchè è ancora presente una tupla. Per ogni tupla setta un parametro su Command2 e recupera un nuovo DataReader (childReader) sempre sulla stessa connessione. Dopo aver effettuato le opportune operazioni il childReader viene chiuso e si prosegue con la riga successiva.
  • 67. ADO.NET Databinding ADO.NET & Data Component
  • 68. DataBinding.: Cos’è il Databinding? (1) Databinding letteralmente significa “legame” ed è l‟attività che permette di stabilire automaticamente lo scambio di valori tra controllo e una sorgente dati. Il databinding evita codice noioso e ripetitivo nel quale assegniamo i dati al controllo e successivamente li riassegnamo alla sorgente dati. Il binding con DataSource poveri implica luso di reflection e quindi impoverisce le performance. Se invece il DataSource implementa le interfacce giuste il discorso è molto diverso.
  • 69. DataBinding: Cos’è il Databinding? (2) In ADO.NET le sorgenti dati disconnesse non hanno più il concetto di record corrente. Il binding di dotnet è gestito da un intermediario tra controllo e sorgente dati che implementa la classe base BindigManagerBase. La presenza di un unico intermediario per “bindare” più controlli garantisce il sync tra questi. Ovviamente se non si desidera una sincronizzazione tra i controllo, basta creare più binder. Sync BindingMan Data agerBase BindingManag erBase Sync Data BindingManag erBase
  • 70. DataBinding:Il Binding Manager Il Binding Manager è lintermediario ed è univoco per ogni datasource. Per ogni binding manager ci sono uno o più controlli, permettendo così, eventualmente, di sincronizzarli durante la navigazione dei dati. Come detto, la classe base del binding manager è BindingManagerBase (astratta) e ha due classi derivate: PropertyManager gestisce il binding con singoli elementi CurrencyManager gestisce il binding con liste di elementi
  • 71. DataBinding: BindingContex Il BindingContext è il contesto di binding, ovvero una lista di BindingManagerBase mantenuta tramite Hashtable. Poiché il nome del datasource è parte della chiave della Hashtable, non più di un BindingManagerBase con lo stesso datasource può esistere in un BindingContext Perciò per non avere sync tra due controlli, i due BindingManagerBase devono appartenere a due BindingContext diversi BindingContext (Hashtable) BindingManagerBase Sync Data BindingManagerBase BindingContext (Hashtable)
  • 72. DataBinding: Simple & Complex Databinding (1) Possiamo avere due forme di DataBindig: Simple & Complex. Un databindind è Simple quando s associa un singolo campo informazione (field) ad una singola proprietà di un componente. Ad esempio la proprietà Text della TextBox associato ad un campo di un db. Nel caso di binding più elaborato, come può essere il collegamento ad un DataGridView, si parla invece di ComplexBindig ed è richiesto un supporto ad- hoc da parte del controllo.
  • 73. DataBinding: Simple & Complex Databinding (2) CurrencyManager BindingContext oppure PropertyManager BindingManagerBase BindingManagerBase DataSource Data Simple Binding DataMember Bindings Binding Control BindingsCollection Binding oppure PropertyName ControlBindingsCollection Binding BindingContext Complex Binding BindingManagerBase Data DataSource Simple Binding DataMember Binding Control PropertyName
  • 74. DataBinding: Simple Binding Come detto il SimpleBinding associa un qualsiasi tipo ad un controllo in modo da semplificare la presentazione di un valore e poterlo aggiornare Proprietà DataMember controllo DataSource int i=5; myLabel.DataBindings.Add("Text", i, null); se è null viene usato ToString() Il binding con un singolo elemento implica luso di PropertyManager  La proprietà Position sarà sempre 0 Il binding con una lista di elementi implica luso di CurrencyManager che ha il concetto di record corrente. • Si usa Position per navigare le righe mostrate • Non si usa Position per leggere la posizione perchè la lista potrebbe contenere elementi che non vengono mostrati (es. filtro sulla dataview) • Si usa Current per leggere lelemento nella lista sottostante (datasource)
  • 75. DataBinding: Simple Binding, format and parse La classe binding (disponibile solo nel simple binding) offre due eventi importanti: • format. Intercetta il dato proveniente dal DataSource prima che venga impostato nel controllo. • parse. Intercetta il dato che dal controllo sta per essere trasferito al DataSource Catturare e gestire questi eventi permette dimigliorare la qualità della visualizzazione dei dati secondo le proprie necessità. Non è utile alla validazione che deve essere effettuata dagli appositi validation- control.
  • 76. DataBinding: Complex Bindig Il ComplexBindig permette (attraverso gli oggetti ADO.NET) di creare rappresentazione complesse dei dati ed operare con essi. DataSource DataMember IList IListSource.GetList() DataSet { return this.DefaultView; } DataTable DataView DataRow DataRowView DataRow DataRowView DataRow DataRowView
  • 77. DataBinding: Complex Bindig (2) Per connettere un datasource ad un componente evoluto, si deve: 1. settare la proprietà Component.DataSource = myDataSet 2. settare la proprietà Component.DataMember = myTable.myColumn E‟ buona norma non specificare mai nel DataSource myDataSet.myTable perché: •il nome del DataSource funge da Key in BindingContext •il designer usa la convenzione in alto Quando si usa il CurrencyManager, può essere necessario usare il suo metodo Refresh affinché il controllo venga aggiornato. La Listbox ha bisogno di questo refresh mentre altri controlli no. Affinché il DataSource sia sicuramente aggiornato è necessario chiamare EndCurrentEdit
  • 78. DataBinding: Non solo database Non è detto che si debbano collegare i componenti solo ed esclusivamente ad un DataSet. Posso infatti creare anche creare una comune collection (list, arraylist, ecc) e collegarla come sorgente dati System.Collections.Arraylist list = new System.Collections.Arraylist(); list.add(new item(”Woot”)); list.add(new item(”Funky”)); list.add(new item(”EarthCrack”)); _randomListbox.DataSource = list; _randomListbox.DisplayValue = “SmackTalk”;
  • 79. ADO.NET: ConclusioniADO.NET 2 è un framework complesso che permette di lavorare in modoefficiente ed efficace con la grande maggioranza delle fonti dati oggidisponibili.L‟infrastruttura permette agli Sviluppatori di concentrasi sulle questioni dibusiness evitando di scrivere codice ridondante e perdere intere giornate inattività di debugging.