.NET Data Access and Manipulation ADO.NET .NET Data Access and Manipulation
Overview What is ADO.NET? Disconnected vs. connected data access models ADO.NET Architecture ADO.NET Core Objects Steps of Data Access Advanced Techniques and UI Tools
What is ADO.NET? ADO.NET is an object-oriented set of libraries that allows you to interact with data sources. Commonly, the data source is a database, but it could also be a text file, an Excel spreadsheet, or an XML file A data-access technology that enables applications to connect to data stores and manipulate data contained in them in various ways ADO.NET is a data access technology from Microsoft .Net Framework , which provides communication between relational and non-relational systems through a common set of components
What is ADO.NET? An object oriented framework that allows you to interact with database systems
Objective of ADO.NET Support disconnected data architecture, Tight integration with XML, Common data representation Ability to combine data from multiple and varied data sources Optimized facilities for interacting with a database
ADO.NET Architecture
ADO.NET Core Objects Core namespace: System.Data .NET Framework data providers: Data Provider Namespace Data Source Description SQL Server System.Data.SqlClient For interacting with Microsoft SQL Server. OLE DB System.Data.OleDb Data Sources that expose an OleDb interface, i.e. Access or Excel. ODBC System.Data.Odbc Data Sources with an ODBC interface. Normally older data bases. Oracle System.Data.OracleClient For Oracle Databases.
ADO.NET Core Objects Object Description Connection Establishes a connection to a specific data source. (Base class: DbConnection) Command Executes a command against a data source. Exposes Parameters and can execute within the scope of a Transaction from a Connection. (The base class: DbCommand) DataReader Reads a forward-only, read-only stream of data from a data source. (Base class: DbDataReader) DataAdapter Populates a DataSet and resolves updates with the data source. (Base class: DbDataAdapter) DataTable Has a collection of DataRows and DataColumns representing table data, used in disconnected model DataSet Represents a cache of data. Consists of a set of DataTables and relations among them
Connected Data Access Model
Disconnected Data Access Model
Pros and Cons - + Connected Disconnected Database Resources Network Traffic Memory Usage Data Access
Connected MODEL
Steps of Data Acces : Connected Environment Create connection Create command (select-insert-update-delete) Open connection If SELECT -> use a DataReader to fetch data If UPDATE,DELETE, INSERT -> use command object’s methods Close connection
The SqlConnection Object Creating Sql Connection SqlConnection conn = new SqlConnection( "Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI"); SqlConnection conn = new SqlConnection("Data Source=DatabaseServer;Initial Catalog=Northwind;User ID=YourUserID;Password=YourPassword"); Connection String Parameter Name Description Data Source Identifies the server. Could be local machine, machine domain name, or IP Address. Initial Catalog Database name. Integrated Security Set to SSPI (Security Support Provider Interface)to make connection with user’s Windows login User ID Name of user configured in SQL Server. Password Password matching SQL Server User ID.
SqlDataReader rdr = cmd.ExecuteReader(); The SqlCommand Object A SqlCommand object allows you to specify what type of interaction you want to perform with a database. For example, you can do select, insert, modify, and delete commands on rows of data in a database table. The SqlCommand object can be used to support disconnected data management scenarios SqlCommand cmd = new SqlCommand("select CategoryName from Categories", conn); Querying Data When using a SQL select command, you retrieve a data set for viewing. To accomplish this with a SqlCommand object, you would use the ExecuteReader method, which returns a SqlDataReader object. SqlDataReader rdr = cmd.ExecuteReader();
SQL COmmand Inserting Data To insert data into a database, use the ExecuteNonQuery method of the SqlCommand object. string insertString = @" insert into Categories (CategoryName, Description) values ('Miscellaneous', 'Whatever doesn''t fit elsewhere')"; // 1. Instantiate a new command with a query and connection SqlCommand cmd = new SqlCommand(insertString, conn); // 2. Call ExecuteNonQuery to send command cmd.ExecuteNonQuery();
SQL COmmand Updating Data The ExecuteNonQuery method is also used for updating data // prepare command string string updateString = @" update Categories set CategoryName = 'Other' where CategoryName = 'Miscellaneous'"; // 1. Instantiate a new command with command text only SqlCommand cmd = new SqlCommand(updateString); // 2. Set the Connection property cmd.Connection = conn; // 3. Call ExecuteNonQuery to send command cmd.ExecuteNonQuery();
SQL Command Getting Single values Sometimes all you need from a database is a single value, which could be a count, sum, average, or other aggregated value from a data set. The following example shows how to do this with the executeScalar method // 1. Instantiate a new command SqlCommand cmd = new SqlCommand("select count(*) from Categories", conn); // 2. Call ExecuteNonQuery to send command int count = (int)cmd.ExecuteScalar();
SQL Command FOR XML AUTO — Builds a tree based on the tables in the FROM clause FOR XML RAW — Maps result set rows to elements with columns mapped to attributes FOR XML EXPLICIT — Requires that you specify the shape of the XML tree to be returned static void ExecuteXmlReader() { string select = "SELECT ContactName,CompanyName " +"FROM Customers FOR XML AUTO"; SqlConnection conn = new SqlConnection(GetDatabaseConnection()); conn.Open(); SqlCommand cmd = new SqlCommand(select, conn); XmlReader xr = cmd.ExecuteXmlReader(); xr.Read(); string data; do data = xr.ReadOuterXml(); if (!string.IsNullOrEmpty(data)) Console.WriteLine(data); } while (!string.IsNullOrEmpty(data)); conn.Close(); }
Reading Data with the SqlDataReader A SqlDataReader is a type that is good for reading data in the most efficient manner possible. You can *not* use it for writing data. You can read from SqlDataReader objects in a forward-only sequential manner. Once you’ve read some data, you must save it because you will not be able to go back and read it again. Creating a SqlDataReader Object SqlDataReader rdr = cmd.ExecuteReader(); Reading Data while (rdr.Read()) { // get the results of each column string contact = (string)rdr["ContactName"]; string company = (string)rdr["CompanyName"]; string city = (string)rdr["City"]; // print out the results Console.Write("{0,-25}", contact); Console.Write("{0,-20}", city); Console.Write("{0,-25}", company); Console.WriteLine(); }
EXAMPLE static void Main() { string connectionString = Properties.Settings.Default.connStr; string queryString = "SELECT CategoryID, CategoryName FROM dbo.Categories;"; SqlConnection connection = new SqlConnection(connectionString); SqlCommand command = new SqlCommand(queryString,connection); try connection.Open(); SqlDataReader reader = command.ExecuteReader(); while (reader.Read()) Console.WriteLine("\t{0}\t{1}“,reader[0],reader[1]); } reader.Close(); connection.close(); catch (Exception ex) Console.WriteLine(ex.Message); EXAMPLE
Stored Procedures A stored procedures is a pre-defined, reusable routine that is stored in a database. SQL Server compiles stored procedures, which makes them more efficient to use. Therefore, rather than dynamically building queries in your code, you can take advantage of the reuse and performance benefits of stored procedures. let the SqlCommand object know which stored procedure to execute and tell the SqlCommand object that it is executing a stored procedure. These two steps are shown below: // 1. create a command object identifying the stored procedure SqlCommand cmd = new SqlCommand("Ten Most Expensive Products", conn); // 2. set the command object so it knows to execute a stored procedure cmd.CommandType = CommandType.StoredProcedure;
Type the following in SQL Query Analyzer: Start->Programs->Microsoft SQL Server->Query Analyzer CREATE PROCEDURE EmpProc(@ EmployeeId INTEGER, @FirstName NCHAR(25)) AS SET NOCOUNT ON UPDATE Employees SET FirstName=@FirstName WHERE EmployeeId=@EmployeeId C# Program: SqlConnection con=new SqlConnection(“---”); con.open(); SqlCommand scmd=CommandType.StoredProcedure; Scmd.Prameters.Add(new SqlParameter(“@EmployeeId”,SqlDbType.Int,0,”EmployeeId”)); Scmd.Prameters.Add(new SqlParameter(“@FirstName”,SqlDbType.NChar,50,”FirstName”)); Scmd.UpdatedRowSource=UpdatedRowSource.None; Scmd.Parameters[0].Value=999; Scmd.Parameters[1].Value=“Raja”; Scmd.ExecuteNonQuery(); String s=scmd.Parameters[1].Value.ToString(); Messagebox.Show(s);
Disconnected Model
DataSet A DataSet is an in-memory data store that can hold numerous tables. DataSets only hold data and do not interact with a data source. This is a collection of DataTables . We use the DataSet type to store many DataTables in a single collection. Conceptually, the DataSet acts as a set of DataTable instances. The SqlDataAdapter that manages connections with the data source and gives us disconnected behavior
Steps Creating a DataSet Object DataSet dsCustomers = new DataSet(); The DataSet constructor doesn’t require parameters. However there is one overload that accepts a string for the name of the DataSet, which is used if you were to serialize the data to XML. Creating A SqlDataAdapter The SqlDataAdapter holds the SQL commands and connection object for reading and writing data SqlDataAdapter daCustomers = new SqlDataAdapter("select CustomerID, CompanyName from Customers", conn); The SQL select statement specifies what data will be read into a DataSet. The connection object, conn, should have already been instantiated, but not opened. It is the SqlDataAdapter’s responsibility to open and close the connection during Fill and Update method calls.
Steps SqlCommandBuilder: There are two ways to add insert, update, and delete commands: via SqlDataAdapter properties or with a SqlCommandBuilder. Here’s how to add commands to the SqlDataAdapter with the SqlCommandBuilder SqlCommandBuilder cmdBldr = new SqlCommandBuilder(daCustomers); This tells the SqlCommandBuilder what SqlDataAdapter to add commands to Filling the DataSet Once you have a DataSet and SqlDataAdapter instances, you need to fill the DataSet. daCustomers.Fill(dsCustomers, "Customers"); The Fill method, in the code above, takes two parameters: a DataSet and a table name. The DataSet must be instantiated before trying to fill it with data. The second parameter is the name of the table that will be created in the DataSet. You can name the table anything you want. Its purpose is so you can identify the table with a meaningful name later on. Typically, I’ll give it the same name as the database table.
Disconnected – Update, Delete, Insert SqlDataAdapter da = new SqlDataAdapter(); DataSet ds = new DataSet(); SqlCommandBuilder cmdBuilder = new SqlCommandBuilder(da); da.Fill(ds); INITIAL CODE DataRow dr = ds.Tables[0].Rows[0]; dr.Delete(); da.UpdateCommand = builder.GetUpdateCommand(); da.Update(ds); DELETE DataRow dr = ds.Tables[0].Rows[0]; dr["CustomerName"] = "John"; da.UpdateCommand = builder.GetUpdateCommand(); da.Update(ds); UPDATE DataRow dr = ds.Tables[0].NewRow(); dr["CustomerName"] = "John"; dr["CustomerSurName"] = "Smith"; ds.Tables[0].Rows.Add(dr); da.UpdateCommand = builder.GetUpdateCommand(); da.Update(ds); INSERT
EXAMPLE using System; using System.Data; using System.Data.SqlClient; namespace SampleClass { class Program static void Main(string[] args) string connStr = Properties.Settings.Default.connStr; SqlConnection conn = new SqlConnection(connStr); string queryString = "SELECT * from titles;"; SqlDataAdapter da = new SqlDataAdapter(queryString,conn); DataSet ds = new DataSet(); da.fill(ds); // Work on the data in memory using // the DataSet (ds) object } EXAMPLE
Choosing a DataReader or a Dataset The type of functionality application requires should be considered Use a dataset to: Cache data locally in your application so that you can manipulate it Remote data between tiers or from an XML Web service Interact with data dynamically such as binding to a Windows Forms control or combining and relating data from multiple sources Perform extensive processing on data without requiring an open connection to the data source, which frees the connection to be used by other clients If readonly data is needed use DataReader to boost performance
Best Practices Don’t create a new connection string for every code connecting to DB Use app.config file to keep your connection strings through the application scope Right click on project and select properties Select settings from the left tabbed menu add the connection string to the table and save project, Name field is the name of the string to access at runtime Accessing settings at runtime: string connStr = Properties.Settings.Default.connStr; You can keep any other variable to reach at runtime using this technique
Data binding It provide the way to link the contents of a control with a data source. Simple Binding:Controls that contain one value, such as label or text box Complex Binding: Controls populated with rows of data, such as list box, data grid Simple Data Binding: DataBinding.Add(Control Propertey, Data Source,Data Member); Program: Textbox1.DataBindings.Add(“Text”,ds,”Employes.EmployeeID”); Textbox2.DataBindings.Add(“Text”,ds,”Employes.Name”); Complex Data Binding: Two Properties: DataSource, Display Member Sda.Fill(ds,”Employees”); DataTable dt=ds.Tables[0]; ListBox.DataSource=ds; Listbox.DisplayMember=“Employees.FirstName”;
using System; using System. Drawing; using System using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Data.SqlClient; public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.TextBox textBox2; private System.Windows.Forms.Button buttonBack; private System.Windows.Forms.Button buttonNext; private System.Data.DataSet dataSet1; private System.ComponentModel.Container components = null; private BindingManagerBase bMgr;
public Form1() { InitializeComponent(); } private void InitializeComponent() { this.textBox1 = new System.Windows.Forms.TextBox(); this.textBox2 = new System.Windows.Forms.TextBox(); this.buttonBack = new System.Windows.Forms.Button(); this.buttonNext = new System.Windows.Forms.Button(); this.dataSet1 = new System.Data.DataSet(); ((System.ComponentModel.ISupportInitialize)(this.dataSet1)).BeginIn it(); this.SuspendLayout(); this.textBox1.Location = new System.Drawing.Point(8, 8); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(160, 20); this.textBox1.TabIndex = 0;
this. textBox1. Text = "textBox1"; this. textBox2 this.textBox1.Text = "textBox1"; this.textBox2.Location = new System.Drawing.Point(8, 40); this.textBox2.Name = "textBox2"; this.textBox2.Size = new System.Drawing.Size(160, 20); this.textBox2.TabIndex = 1; this.textBox2.Text = "textBox2"; this.buttonBack.Location = new System.Drawing.Point(24, 80); this.buttonBack.Name = "buttonBack"; this.buttonBack.Size = new System.Drawing.Size(56, 23); this.buttonBack.TabIndex = 2; this.buttonBack.Text = "<< Back"; this.buttonBack.Click += new System.EventHandler(this.buttonBack_Click); this.buttonNext.Location = new System.Drawing.Point(96, 80); this.buttonNext.Name = "buttonNext"; this.buttonNext.Size = new System.Drawing.Size(56, 23);
this. buttonNext. TabIndex = 3; this. buttonNext this.buttonNext.TabIndex = 3; this.buttonNext.Text = "Next>>"; this.buttonNext.Click += new System.EventHandler(this.buttonNext_Click); this.dataSet1.DataSetName = "NewDataSet"; this.dataSet1.Locale = new System.Globalization.CultureInfo("en-US"); this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(176, 108); this.Controls.Add(this.buttonNext); this.Controls.Add(this.buttonBack); this.Controls.Add(this.textBox2); this.Controls.Add(this.textBox1); this.Name = "Form1"; this.Text = "Form1"; this.Load += new System.EventHandler(this.Form1_Load);
((System. ComponentModel. ISupportInitialize)(this. dataSet1)) ((System.ComponentModel.ISupportInitialize)(this.dataSet1)).EndInit (); this.ResumeLayout(false); } static void Main() { Application.Run(new Form1()); private void Form1_Load(object sender, System.EventArgs e) { string connString = "server=(local)\\SQLEXPRESS;database=MyDatabase;Integrated Security=SSPI"; string sql = @"select * from employee "; SqlConnection conn = new SqlConnection(connString); SqlDataAdapter da = new SqlDataAdapter(sql, conn); da.Fill(dataSet1, "employee"); textBox1.DataBindings.Add("text", dataSet1, "employee.firstname");
textBox2. DataBindings. Add("text", dataSet1, "employee textBox2.DataBindings.Add("text", dataSet1, "employee.lastname"); bMgr = this.BindingContext[dataSet1, "employee"]; } private void buttonNext_Click(object sender, System.EventArgs e) { bMgr.Position += 1; private void buttonBack_Click(object sender, System.EventArgs e) { bMgr.Position -= 1;