Webocreation

Monday, October 11, 2010

Creating DataAdapter Object


Creating DataAdapter Object

The overloaded constructor for the DataAdapter allows four different ways to create the data adapter, of which two are most commonly used. The following example creates a DataAdapter specifying the SELECT statement and connection string in the constructor.
String connString = "Data Source=(local);Integrated security=SSPI;" + 
    "Initial Catalog=Northwind;";
String selectSql = "SELECT * FROM Orders";
 
SqlDataAdapter da = new SqlDataAdapter(selectSql, connString);
While this approach is common, it is awkward when using parameterized queries or stored procedures. The following example creates a DataAdapter specifying a Command object for the SelectCommand property of the DataAdapter in the constructor:
// create the Connection
String connString = "Data Source = (local);Integrated security = SSPI;" + 
    "Initial Catalog = Northwind;";
SqlConnection conn = new SqlConnection(connString);
 
// create a Command object based on a stored procedure
String selectSql = "MyStoredProcedure";
SqlCommand selectCmd = new SqlCommand(selectSql, conn);
selectCmd.CommandType = CommandType.StoredProcedure;
 
SqlDataAdapter da = new SqlDataAdapter(selectCmd);
It should be noted that there is no best way to create a DataAdapter, and it makes no real difference how it is created.

Retrieving Data from the Data Source

The Fill( ) method of the DataAdapter retrieves data from the data source into a DataSet or a DataTable. When the Fill( ) method for the data adapter is called, the select statement defined in the SelectCommand is executed against the data source and retrieved into a DataSet or DataTable. In addition to retrieving data, the Fill( ) method retrieves schema information for columns that don't exist. This schema that it retrieves from the data source is limited to the name and data type of the column. If more schema information is required, the FillSchema( ) method can be used. The following example shows how to use the Fill( ) method to retrieve data from the Orders table in the Northwind database:
// connection string and the select statement
String connString = "Data Source=(local);Integrated security=SSPI;" + 
    "Initial Catalog=Northwind;";
String selectSQL = "SELECT * FROM Orders";
 
SqlDataAdapter da = new SqlDataAdapter(selectSQL, connString);
 
// create a new DataSet to receive the data
DataSet ds = new DataSet();
 
// read all of the data from the orders table and loads it into the
// Orders table in the DataSet
da.Fill(ds, "Orders");
A DataTable can also be filled similarly:
// ... code to create the data adapter, as above
 
// create the DataTable to retrieve the data
DataTable dt = new DataTable("Orders");
 
// use the data adapter to load the data into the table Orders
da.Fill(dt);
Notice that a connection object is never opened and closed for the data adapter. If the connection for the data adapter isn't open, the DataAdapter opens and closes it as required. If the connection is already open, the DataAdapter leaves the connection open.
The same set of records can be retrieved more efficiently using a stored procedure. Stored procedures have a number of benefits over SQL statements:
·         Stored procedures allow business logic for common tasks to be consistently implemented across applications. The stored procedure to perform a task can be designed, coded, and tested. It can then be made available to any client that needs to perform the task. The SQL statements to perform the task need to be changed in only one place if the underlying business logic changes. If the parameters for the stored procedure don't change, applications using the stored procedure will not even need to be recompiled.
·         Stored procedures can improve performance in situations where a group of SQL statements are executed together with conditional logic. A stored procedure allows a single execution plan to be prepared for the SQL statements together with the conditional logic. Rather than having the client submit a series of SQL statements based on client-side conditional logic, both the SQL statements and conditional logic are executed on the server, requiring only one round trip. Additionally, when a stored procedure is executed, only the parameters need to be transmitted to the server rather than the entire SQL statement.
·         Stored procedures are more secure. Users can be granted permission to execute stored procedures that perform required business functions rather than having direct access to the database tables.
·         Stored procedures provide a layer of abstraction for the data, making performing business function more intuitive and, at the same time, hiding database implementation from the users.
There are several options available to load more than one table into the same DataSet using a DataAdapter:
·         The Fill( ) method can be called several times on the same DataAdapter, specifying a different DataTable in the same DataSet. The SelectCommand is modified to select the records for a different table each time Fill( ) is called.
·         Multiple DataAdapter objects, each returning one table, can be created. Fill( ) is called on each DataAdapter, specifying the appropriate DataTable in the same DataSet.
·         Either a batch query or a stored procedure that returns multiple result sets can be used.
In the last option, the DataAdapter automatically creates the required tables and assigns them the default names Table, Table1, Table2, if a table name isn't specified. If a table name is specified, for example MyTable, the DataAdapter names the tables MyTable, MyTable1, MyTable2, and so on. The tables can be renamed after the fill, or table mapping can map the automatically generated names to names of the underlying tables in the DataSet. The following example shows how to use a batch query with a DataAdapter to create two tables in a DataSet:
// connection string and batch query
String connString = "Data Source=(local);Integrated security=SSPI;" + 
    "Initial Catalog=Northwind;";
String selectSql = "SELECT * FROM Customers;" + 
    " SELECT * FROM Orders";
 
// create the data adapter
SqlDataAdapter da = new SqlDataAdapter(selectSql, connString);
 
// create and fill the DataSet
DataSet ds = new DataSet();
da.Fill(ds);
The DataSet is filled with two tables named Table and Table1, respectively, containing data from the Customers and the Orders tables in data source.
Finally, the DataAdapter provides an overloaded Fill( ) method that retrieves a subset of rows from the query and loads them into the DataSet. The starting record and maximum number of records are specified to define the subset. For example, the following code statement retrieves the first 10 records and inserts them into a DataTable named Categories:
da.Fill(ds, 0, 10, "Categories");
It is important to realize that this method actually performs the original query and retrieves the full set of results. It then discards those records that aren't in the specified range. As a result, this approach performs poorly when selecting from large result sets. A better approach is to limit the amount of data that must be transferred over the network and the work that must be performed by the data source by fine-tuning a SQL SELECT statement using a TOP n or WHERE clause.

No comments:

Post a Comment