FEN Data connection DataReader DataSet Bonus info: Concurrency and Database Transactions Embedded SQL
2 Architecture FEN DB DBMS DB Server We need something to make it fit together! SQL Management Tool Client SQL Table OO programme ?????
3 Architecture FEN DB DBMS DB Server DB Access Layer Client – OO programme SQL
FEN DBConnection Connection: Open Connection Execute DB operations Close Connection Working on actual (live) data Other applications can not access data.
FEN Overview of using databases 4 steps: 1.Open connection to database 2.Execute SQL for updating DB or fetching records (rows in the result table) 3.Handle data 4.Close connection
FEN Step 1: Open Connection Connection are opened according to connection string info here is a connection to a MS SQL Server database opened The database is located Source=NO122065\MSSQLSRV2012;” (my SQL Server) means that escape characters are discarded) Name of the database: Initial Catalog=MiniBankAK connection // Create and open a connection. SqlConnection cn = new SqlConnection(); cn.ConnectionString Source=NO122065\MSSQLSRV2012;” +”Initial Catalog=MiniBankAK;Integrated Security=True"; cn.Open(); ShowConnectionStatus(cn); Connection See ado\ReaderExample01ado\ReaderExample01
FEN Connection Strings Connection strings are product specific (DB specific) and often very well-documented. Help may be found at: If you are on the.NET platform using Visual Studio and MS SQL Server, VS can help. See ado\ReaderExample01ado\ReaderExample01
Short exercise: Change the connection string in ado\ReaderExample01, so that the example works on our PC. ado\ReaderExample01 FEN
9 Two ways of DB access Connected: Open connection. Read/Write access (select, insert, update and delete) using a Command object. When reading (select) a DataReader object is returned. A DataReader is an iterator (cursor) into the result table. Close Connection. Disconnected: Fill a DataSet object (a copy of a part of the database) using a DataAdapter. DataAdapter wraps SQL-statement(s). A DataSet object contains DataTable objects. DataTable objects contain collections of rows and columns.
FEN Data are fetched by creating a Command object and use it to execute a SQL statement. Data can be stored in either a DataReader object or a DataSet object. Using DataReader the result table lives server side, and you look at live data. Using DataSet the result table(s) is (are) copied to the client, and live data may be changed by other users. Step 2: Get / fetch data from the database
FEN Connection vs. Connectionless Connection: Open Connection Execute DB operations Close Connection Working on actual (live) data Other applications can not access data.
FEN Connection vs. Connectionless Connectionless: –Create a copy of a part of the database –Execute DB operations on the copy –Other applications may change date –The copy may be come inconsistent. Data are changed in the local copy: –at update it is checked if the data in the database have been modified by others –in that case the update is rejected (ConcurrencyException).
FEN Differences between DataReader and DataSet/DataAdapter DataReader can only be used for reading data. It can only be traversed once (forward). DBCommand can update the database by ExecuteNonQuery. This update is executed immediately. DataAdapter is the connection between DataSet and database. Data are fetched to the DataSet, might be modified and sent back to the database. Updates are executed on a local copy. Concurrency problems must be handled. Possible to traverse forward and backward. A DataSet can contain multiple tables. We will focus on DataReader.
FEN Step 2: Get records using DataReader Get records via SQL Select query read-only access to the database string strSQL = "SELECT * FROM Customer"; SqlCommand myCommand = new SqlCommand(strSQL, cn); SqlDataReader myDataReader; myDataReader = myCommand.ExecuteReader(); data reader record
FEN What is achieved so far? We have created a connection to a database. The connection is placed in the connection object. We have done a search by using a SQL-statement. The search was executed by using a command object. The result of the search was stored in a DataSet or as here a DataReader object. Now it is possible to get the data from this object for viewing, passing on to client or handle in other ways.
FEN Step 3: Getting the result and handle data Loop through the result table row by row. For each row: get the attribute value: SqlDataReader myDataReader; myDataReader = myCommand.ExecuteReader(); // Loop over the results. while (myDataReader.Read())//while(more rows) { Console.WriteLine("Custno: {0}, Name: {1} ", myDataReader.GetInt32(0), myDataReader.GetString(1).Trim()); } data reader record
FEN This is very flexible, one need to the details of the result table. This is more flexible: // Loop over the results. while (myDataReader.Read())//while(more rows) { //Display each attribute in current row for (int i = 0; i < myDataReader.FieldCount; i++) { Console.Write("{0} = {1} ", myDataReader.GetName(i), myDataReader.GetValue(i).ToString().Trim()); } Console.WriteLine(); } See ado\ReaderExample02ado\ReaderExample02 Step 3: Getting the result and handle data
FEN myDataReader.Close(); cn.Close(); Step 4: Close the connection DataReaders work on live data, locking other user out, so remember: Close DataReader and connection when you are done:
Short exercise: Change the connection string in ado\ReaderExample02, so that the example works on our PC. ado\ReaderExample02 Change the example (connections string and SQL statement), so the VW-database is accessed and this SQL query (query 4) is executed: FEN select distinct model from Car, spc where Car.cNo = spc.cNo and sNo='s1'
FEN public class Customer { private int custNo; private string name; private List accounts; public Customer(int cNo, string n) { this.custNo= cNo; this.name= n; accounts = new List (); } //--- Building objects You can do more than just printing the result. For instance, assume that you have this class:
FEN SqlDataReader myDataReader; myDataReader = myCommand.ExecuteReader(); List customers = new List (); // Loop over the results. // Create objects and add them to a list while (myDataReader.Read())//while(more rows) { int custNo = myDataReader.GetInt32(0); string custName = myDataReader.GetString(1).Trim(); Customer c = new Customer(custNo, custName); customers.Add(c); } Building objects Then objects may build from the database: See ado\ReaderExample03ado\ReaderExample03
FEN Console.WriteLine(); Console.Write("Close connections?"); Console.ReadLine(); Console.WriteLine(); myDataReader.Close(); cn.Close(); Console.WriteLine(); Console.Write("Show customer list?"); Console.ReadLine(); foreach(Customer c in customers) Console.WriteLine(c); Console.WriteLine(); Building objects Then the connection may be closed, and you can use the objects in your application: DB Connection is closed Objects are used as POCOs (”Plain Old C# Objects”) Objects are used as POCOs (”Plain Old C# Objects”) See ado\ReaderExample03ado\ReaderExample03
FEN //get new value Console.Write("Enter customer number: "); int custNo = Convert.ToInt32(Console.ReadLine()); Console.Write("Enter new customer name: "); string custName = Console.ReadLine(); cn.Open(); //Build SQL statement: strSQL = "UPDATE Customer SET name = '" + custName + "' WHERE custNo = " + custNo; myCommand = new SqlCommand(strSQL, cn); myCommand.ExecuteNonQuery(); cn.Close(); Updating the database Update (or insert or delete): ExecuteNonQuery See ado\UpdatingReaderado\UpdatingReader
FEN Bonus info: Database Transactions A database normally has many users at the same time (concurrency): My bank account: I am at my wine merchant trying to buy 12 bottles of Chambertin using my card. At the same time my wife using home banking is trying to move my money to our savings account. Who wins? Many database operations requires more than SQL statement to be executed: Transferring an amount from my account to our savings account: the amount must be withdrawn from my account (one SQL update) and inserted to our savings account (another SQL update). We want both update to complete (or non), but nor just one of the updates. This is known as an transaction: Both updates or non!
FEN Bonus info: Database Transactions ACID: Atomic Consistent Isolation Durability Problems: lost update “dirty read”, uncommitted dependency, temporary update inconsistent analysis (incorrect summary) Synchronization is needed
FEN Bonus info: Database Transactions T1:Transfers N DKKs from account X to account Y: read_item(X); X:= X-N; write_item(X); read_item(Y); Y:= Y+N; write_item(Y); T2:Deposits M DKK on account Y: read_item(Y); Y:= Y+M; write_item(Y); Any possible problems? time
FEN Bonus info: Lost Update
FEN Bonus info: Dirty Read (Uncommitted dependency)
FEN Bonus info: Inconsistent Analysis
FEN Database Transactions: C#/ADO.NET/MS SQL Server ado\BankTransactions