Copyright ©2004 Virtusa Corporation | CONFIDENTIAL ADO.Net Basics Ruwan Wijesinghe Trainer
2 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Introduction ADO.NET is the library in.NET Framework, used to access Data. This is a fully object oriented, XML based library which provides a consistent user interface for any Data Source, including XML.
3 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Design Goals Use existing ADO experience. Support for N-Tire distributed applications (XML based serialization and disconnected datasets). Integrated XML support (Enables to access XML data using familiar Relational Database Structure).
4 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Architecture Separate Data Access from Data Manipulation. DataSet DbConnection DbParameters DbCommand DbDataReader DbDataAdapter Select Command Insert Command Delete Command Update Command Fill Update
5 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Data Access Classes DbConnection This is the link between the database and the application. A connection string is used to identify the database to connect. DbCommand This class is used to execute SQL commands, on the database. This class uses connection object to access the database. DbDataReader This class is used to retrieve data from a database. Data access is read-only and forward-only. DbDataAdapter This class is used to fill and update DataSets. This class uses Command objects to send and receive data.
6 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Connection String The connection string is a list of parameters, separated by “;” character. Some important parameters are given below. Provider – The Ole-DB database driver name (used only in Ole-DB connections. Data Source – The source of data. This value depends on the database server. This is the server name for SQL Server database and database file name for Microsoft Access. Initial Catalog – This is the initial database name. This parameter is not used with Microsoft Access connection. Connection Timeout / Connect Timeout – The duration which the connection should keep trying to establish the connection. The default value is 15s. User ID – The user account, which is used to access the database Password – The password for the above user account
7 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Database Connections Important facts about connections Number of connections that can be opened simultaneously is limited. Opening a connection is a quite expensive process. Therefore the connections that you made using the same connection string are pooled by ADO.NET. When we open a connection, ADO.NET will return a connection from the pool, if available. Since the number connections in the pool is limited, release the open connections by calling Close method, as soon as possible, so that they will be available for other work.
8 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Get Factory Class for the Desired Provider ADO.Net Support for writing Database independent Database Access Code This is achieved using Factory classes All these database independent data access classes are defined in "System.Data.Commen" namespace Creating the Factory DbProviderFactory factry = DbProviderFactories.GetFactory (stProvidername); Provider Name for SQL client is, "System.Data.SqlClient", this is similar to the namespace name in which SQL client classes are defined.
9 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Creating New Connections and Commands and Parameters Creating Connections DbConnection conn = factry.CreateConnection(); conn.ConnectionString = stConnectionString; Creating Commands DbCommand cmd = factry.CreateCommand(); cmd.Connection = conn; cmd.CommandText = stSQL; Creating Parameters DbParameter para = factry.CreateParameter(); para.ParameterName = para.DbType = DbType.Int32; para.Value = id; cmd.Parameters.Add(para);
10 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Execute SQL Command that does not Return any Value Execute an SQL Command that does not return any value try{ conn.Open(); cmd.ExecuteNonQuery(); } finally{ conn.Close(); }
11 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Execute an SQL Command that Returns Values 1 try { conn.Open(); DbDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { int id = reader.GetInt32(0); string name = reader.GetString(1); double height = reader.GetDouble(2); // Process the values } finally { conn.Close(); }
12 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Execute an SQL Command that Returns Values 2 try { conn.Open(); DbDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { int id = (int) reader["id"]; string name = (string) reader["name"]; double height = (double) reader["height"]; // Process the value } finally { conn.Close(); }
13 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Data Cache DataSets and DataTables are used to temporarily cache the data received from the database DataTable is used to hold the data received from a single SQL query. This corresponds to a table in a database. DataSet is a collection of DataTables. In addtion to that, dataset can contain relationships between tables and constraints. This corresponds the whole database.
14 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Fill a DataTable Fill a DataTable Directly DbDataAdapter adp = factory.CreateDataAdapter(); adp.SelectCommand = cmd; DataTable dt = new DataTable(); adp.Fill(dt); Fill a DataTable in a DataSet DbDataAdapter adp = factory.CreateDataAdapter(); DataSet ds = new DataSet(); adp.Fill(ds,"Students"); return ds;
15 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Using Typed DataSets and Typed DataTables We can use Visual Studio IDE to generate Typed DataSets, which can be used to do type verifications in compilation time. Typed DataSets generated using IDE has Typed DataTables to hold the data belongs to each table handled by the DataSet. Each Typed DataTable in a Typed DataSet has a separate typed DataAdapter class to operate on them. These Typed DataAdapters includes methods to fill and update data in this Typed DataTables In addition to the Fill and Update methods operate on DataTables, we can make IDE to include direct database access functions (GetData, Insert, Delete and Update) to the Typed DataAdapters
16 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Using Typed Adapters 1 Returning a Typed DataTable public DataSet.StudentsDataTable GetAllStudentsDT() { MyDataSetTableAdapters.StudentsTableAdapter adp = new MyDataSetTableAdapters.StudentsTableAdapter(); return adp.GetData(); } Filling a Typed DataTable in a Typed DataSet MyDataSetTableAdapters.StudentsTableAdapter adp = new MyDataSetTableAdapters.StudentsTableAdapter(); MyDataSet ds = new MyDataSet(); adp.Fill(ds.Students);
17 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Using Typed Adapters 2 Create an instance of the Typed Adapter MyDataSetTableAdapters.StudentsTableAdapter adp = new MyDataSetTableAdapters.StudentsTableAdapter(); Delete a Row int id = 5; adp.Delete(id); Update a Row int original_id = 50; //the current id in the database (before update) int new_id = 7; // the next value of the id (after update) string name = "aaa"; double? height = null; //Leave this field blank (unassigned) adp.Update(new_id, name, height, null, original_id);
18 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Processing the Values in a Typed DataSet Calculating the average Height MyDataSet ds = new MyDataSet(); adp.Fill(ds.Students); double total = 0; int count = 0; foreach (MyDataSet.StudentsRow srow in ds.Students) { if (! srow.IsHeightNull()) // This is important to prevent exceptions { total += srow.Height; count++; } double average = total / count;
19 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Reading XML Files DataSets can directly read XML files and map there hierarchical structure in to its relational tables. E.g DataSet ds = new DataSet("MyDS"); ds.ReadXml("E:\\Temp\\test1.xml",XmlReadMode.Auto); dataGrid1.DataSource = ds; Sample XML File These files will create, A table named “Book” (fields “id” and “name”) A table named “Author” (field “name”) A relationship between two tables The data-grid will display the data in a hierarchical way
20 Copyright ©2004 Virtusa Corporation | CONFIDENTIAL Write to XML File We can save the data in a DataSet into an XML file using WriteXML method. The DataSet Name (“MyDS” in this example”) will be the root element of the xml file In order to insure that the relationship is implemented as nested tags in xml file, make sure that the Nested property of the relationship object is set to true. E.g. DataSet ds = new DataSet("MyDs"); sqlDataAdapter1.Fill(ds,"tblStudents"); sqlDataAdapter2.Fill(ds,"tblMarks"); ds.Relations.Add( "MarksOfStudent", ds.Tables["tblStudents"].Columns["id"], ds.Tables["tblMarks"].Columns["stid"]).Nested=true; ds.WriteXml("E:\\Temp\\test2.xml"); We can write the xml file together with the xml Schema infomration like this, ds.WriteXml ("E:\\Temp\\test2.xml", XmlWriteMode.WriteSchema); However this method will not preserve the order of rows as in the database. To keep this information as well, we can save the file as a DiffGram ds.WriteXml ("E:\\Temp\\test2.xml", XmlWriteMode.DiffGram);