A2 Teacher Up skilling LECTURE 3 ADO.NET What’s to come today? • ADO.NET • What is ADO.NET? • ADO.NET Objects • • • • • SqlConnection SqlCommand SqlDataReader DataSet SqlDataAdapter What is ADO.NET? • ADO.NET is a set of classes that allow programmers to interact with a database through programming languages such as C# and Visual Basic. • ADO.NET provides a consistent interface for accessing data through a SQL Server data source, OLE DB data source and ODBC data source. • The classes that ADO.NET provide allows us to send SQL queries through C# statements. • For the purposes of this course we will be using ADO.NET along with SQL Server. ADO.NET can also be used to access and manipulate an Access Database. ADO.NET Architecture ADO.NET Objects • There are a number of key classes that are available in ADO.NET that allows us to work with data in a database. • Briefly they are: • • • SqlConnection - specify the connection to the database. SqlCommand – send SQL statements to the database. SqlDataReader – obtain results from a SELECT SQL statement. • • DataSet – an in memory representation of the database. SqlDataAdapter – exchanges data between a DataSet and a Database. SqlConnection • In order to work with a database, first you have to obtain a connection to it. • As a programmer, we want the ability to open the connection so we can start working with the data, and then close the connection once we are finished. • The SqlConnection class allows us to achieve this. To create a instance of SqlConnection we just need to invoke the SqlConnection constructor with a String parameter that represents our Connection String. • Once you have an instance of SqlConnection, you must invoke the SqlConnection Open() method to open the connection to the database. Connection String • A Connection String is made up of a number of key arguments that are separated by semi-colons: • Data Source – identifies machine that server that database is running on (could be local machine, a certain machine name or an IP address. • • Initial Catalog – Name of the Database. Integrated Security – type of security authentication. Typically set to true. • • User ID (optional) – Perhaps a certain user on a server. Password (optional) – Password for given User ID on server Connection String Configuration • The connection string for a database is specified in a configuration file in a project. Typically declared within a <connectionString> XML element. • The reason why we store a Connection String in a configuration file is so that we have a single place of access that all our SqlConnection objects will use to open connections. • If we hardcoded the connection string parameter into every SqlConnection constructor, then if we ever changed the location of our database on a server we would have to go through the C# code and change it in multiple places. • By storing the connection string in a configuration file, we only have to change it in one place. Connection String Configuration (Cont.) • On the next slide there is an example Connection String that is declared in the app.config file of a project. • Along with the actual connection string, we have a name that we can refer to that connection string with, and a provider name which indicates the type of data provider we will use. For this course, we will be using System.Data.SqlClient. • We can access the Connection String in our C# code through the System.Configuration.ConfigurationManager class along with the name of the ConnectionString we have specified. using System.Configuration; string connectionstring = ConfigurationManager.ConnectionStrings[”ConnectionStringName"].Connect ionString; Connection String Example <configuration> <connectionStrings> <add name=”ConnectionStringName" connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\ AnotherDatabase.mdf;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> </configuration> SqlConnection Example • Once we have our connection string set up we can now use it to create a SqlConnection object. • You may notice we have a using() statement around our code. All the using statement does is automatically disposes of our SqlConnection object upon exit of the final curly brace. • We should still close the SqlConnection by calling the Close() method once we are finished working with our database. using (var connection = new SqlConnection(connectionstring)){ //connection open connection.Open(); //... //close sql connection connection.Close(); } SqlCommand • Now that the database connection is open, we want to be able to send our SQL statements to be executed via a SqlCommand object. • • The SqlCommand constructor takes a number of key parameters. The first parameter is the SQL statement that is to be executed in the form of a String. • The second parameter indicates the SqlConnection instance that the SqlCommand should be ran against. SqlCommand selectCustomerCommand = new SqlCommand("SELECT * FROM Customer", connection); SqlCommand deleteCustomerCommand = new SqlCommand(”DELETE FROM Customer WHERE ID = 1", connection); SqlCommand (cont.) • If you are using a SqlCommand object to insert or delete data from the database, then to execute that command you need to use the SqlCommand method ExecuteNonQuery(). This command returns a integer value that indicates the number of rows that were updated. int rowsUpdated = deleteCustomerCommand.ExecuteNonQuery(); • If you are using a SqlCommand to query data that is to be returned, you would use the ExecuteReader() method that returns an instance of a SqlDataReader. SqlDataReader sqlDataReader = selectCustomerCommand.ExecuteReader(); SqlDataReader • The SqlDataReader class is used for reading data efficiently. You can obtain an instance of a SqlDataReader object by invoking the ExecuteReader() method on a SqlCommand object. • Once you have a reference to a SqlDataReader object, you can read data returned from the query row by row. To achieve this we make use of a while loop along with the SqlDataReader method Read(). The Read() method of SqlDataReader returns a boolean indicating whether there are more rows to be read. • You can extract the values of each column in a row by the following syntax: String stringAttribute = (string) reader[“AttributeName”]; String customerName = (string) reader[“CustomerName”]; • You should always invoke the Close() method when you are finished with a DataReader. SqlDataReader Example using (SqlConnection connection = new SqlConnection(connectionstring) { SqlCommand command = new SqlCommand( "SELECT * FROM Customer", connection); connection.Open(); SqlDataReader reader = command.ExecuteReader(); if(reader.HasRows) { while (reader.Read()) { string customerName = (string) reader["CustomerName"]; Console.WriteLine(customerName); } } } DataSet • A DataSet is an in memory temporary data store that can hold a number of tables. • Typically data is loaded into a DataSet on an initial connection with the database. This provides an in-memory cache. • The user can then manipulate the data in the dataset without a connection to the database. • The DataSet keeps track of the changes made to the data and writes all these changes back to the database once they become reconnected. Why would I use a DataSet? • They are useful for two purposes: • Disconnected Data: Customer sales reps could sync their DataSet in the morning and then travel around making modifications to customers data without a connection. Then at the end of the day, update the database with the contents of their DataSet. • Scalability: Imagine you have a website that shows data from the database to the user. Each time a page is loaded, the SqlDataReader has to query the database. If we used a DataSet, we could just check if that data exists in the database, if so just use that data otherwise sync our dataset with the main database. This avoids unnecessary overhead database trips and therefore makes the application more scalable. DataSet & SqlDataAdapter • To create a new DataSet is simple. DataSet customerDataSet = new DataSet(); • In order to load a DataSet you need a Data Adapter. We will use the SqlDataAdapter class. The SqlDataAdapter class is responsible for filling the dataset with data (Fill() method), and updating the database with the data from the dataset (Update() method). • To create a SqlDataAdapter, you invoke the constructor of the SqlDataAdapter class with an instance of a SqlCommand. SqlDataAdapter dataAdapter = new SqlDataAdapter(sqlCommand); Filling a DataSet • The Fill() method takes two parameters. The instance of the DataSet object, and a table name. A table with the table name given will be created in the DataSet. using (var dataAdapter = new SqlDataAdapter(sqlCommand)) { dataAdapter.Fill(dataset, ”Customers"); } Updating a Database with a DataSet • After modifications have been made to a DataSet (perhaps through a Windows Form control such as a DataGrid View), you want the changes made to be sent back to the database to be saved. • To do this we simply call the Update() method with the DataSet and the table name that is to be written back to the database. using (var dataAdapter = new SqlDataAdapter(sqlCommand)) { dataAdapter.Update(dataset, ”Customers"); } What’s to come next time • Week 4 • • • Advanced Joins Stored Procedures Database Access Layer