Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler...

80
Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect TechTalk www.techtalk.at University of Linz, Institute for System Software, 2004 blished under the Microsoft Curriculum License
  • date post

    22-Dec-2015
  • Category

    Documents

  • view

    222
  • download

    4

Transcript of Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler...

Page 1: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

Data Access with ADO.NET

Dr. Herbert PraehoferInstitute for System Software Johannes Kepler University Linz

Dr. Dietrich BirngruberSoftware Architect TechTalkwww.techtalk.at

© University of Linz, Institute for System Software, 2004published under the Microsoft Curriculum License

Page 2: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

ADO.NETIntroduction

Connection-oriented Access

Connectionless Access

Database Access with DataAdapter

Integration with XML

Preview of ADO.NET 2.0

Summary

Page 3: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

3

ADO.NET

• Is the .NET technology for accessing structured data

• Uniform object oriented interface for different data sources

– relational data bases

– XML data

– other data sources

• Designed for distributed and Web applications

• Provides 2 models for data access

– connection-oriented

– connectionless

Page 4: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

4

Idea of the Universal Data Access

• Connection of (object-oriented) programming languages and relational data bases

• Uniform programming model and API

• Special implementations for data sources (providers)

AP

I

Provider

OD

BC

MySql

DB2

OracleApplication

?

Page 5: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

5

Data Providers

Microsoft’s layered architecture for data access

SQL-data

MS SQL Server, Oracle, Jet, Foxpro, ...

SQL ServerOracleMySQL

ODBC

Non-SQL-data

Directory Services, Mail, Text, Video, ...

OLEDB

ADO.NET

Page 6: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

6

History of Universal Data Access (Microsoft)

ODBC OLE DB

ADO (Active Data Objects) ADO.NET

ADO ADO.NET

connection-oriented connection-oriented + connectionless

sequential access main-memory representation with direct access

only one table supported more than one table supported

COM-marshalling XML-marshalling

Page 7: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

7

Database

Connection-oriented data flow

ADO.NET Managed Providers

DataAdapter

Connection

DataReader

Command

Transaction

ADO.NET Content Components

XML file

Connectionless data flow

DataSet

Tables

Relations

DataTable

ReadXmlWriteXml

DataTable DataRelation

Update

Fill

Architecture of ADO.NET

connection-oriented connectionless

Page 8: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

8

Connection-oriented versus Connectionless

• Connection-oriented– Keeps the connection to the data base alive

– Intended for applications with:• short running transactions

• only a few parallel accesses

• up-to-date data

• Connectionless– No permanent connection to the data source

– Data cached in main memory

– Changes in main memory changes in data source

– Intended for applications with:• many parallel and long lasting accesses (e.g.: web applications)

Page 9: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

9

ADO.NET Assembly and Namespaces

Assembly

– System.Data.dll

Namespaces:

– System.Data general data types – System.Data.Common classes for implementing providers– System.Data.OleDb OLE DB provider– System.Data.SqlClient Microsoft SQL Server provider– System.Data.SqlTypes data types for SQL Server– System.Data.Odbc ODBC provider (since .NET 1.1)– System.Data.OracleClient Oracle provider (since .NET 1.1)– System.Data.SqlServerCe Compact Framework

Page 10: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

ADO.NETIntroduction

Connection-oriented Access

Connectionless Access

Database Access with DataAdapter

Integration with XML

Preview of ADO.NET 2.0

Summary

Page 11: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

11

Architecture

• DbConnection– represents connection to the data

source

• DbCommand– represents a SQL command

• DbTransaction– represents a transaction

– commands can be executed within a transaction

• DataReader– result of a data base query

– allows sequential reading of rows Database

ADO.NET Connected Model

.NET Application

DbConnection

Command

DataReader

DbCommand DbTransaction

Page 12: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

12

Class Hierarchy

IDbConnection

IDbCommand

IDbTransaction

IDataReader

• General interface definitionsIDbConnection

IDbCommand

IDbTransaction

IDataReader

• Special implementationsOleDb: implementation for OLEDB

Sql: implementation for SQL Server

Oracle: implementation for Oracle

Odbc: implementation for ODBC

SqlCe: implementation for SQL Server CE data base

OleDbConnection SqlConnection OracleConnection

...

OleDbCommand SqlCommand OracleCommand

OleDbTransaction SqlTransaction OracleTransaction

OleDbDataReader SqlDataReader OracleDataReader

Page 13: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

13

Example: Northwind Database

Microsoft Example for SQL Server

• Reading of the table Employees• Output of

– EmployeesID, LastName, FirstName

for all rows of table Employees

Run

Page 14: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

14

Program Pattern for Connection-oriented Data Access

1.) Declare the connectiontry {

1.) Request connection to database

3.) Process result

2.) Execute SQL statements

4.) Release Resources} catch ( Exception ) {

Handle exception } finally {

try { 4.) Close connection

} catch (Exception) { Handle exception }

}

Page 15: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

15

Example: EmployeeReader (1)using System;using System.Data;using System.Data.OleDb;

public class EmployeeReader {public static void Main() {

// continue next page

string connStr = "provider=SQLOLEDB; data source=(local)\\NetSDK; " + "initial catalog=Northwind; user id=sa; password=; ";

IDbConnection con = null; // declare connection objecttry {

con = new OleDbConnection(connStr); // create connection objectcon.Open(); // open connection

• Establish connection

//----- create SQL command IDbCommand cmd = con.CreateCommand(); cmd.CommandText = "SELECT EmployeeID, LastName, FirstName FROM Employees"; //----- execute SQL command; result is an OleDbDataReaderIDataReader reader = cmd.ExecuteReader();

• Execute command

Page 16: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

16

Example: EmployeeReader (2)

IDataReader reader = cmd.ExecuteReader();object[] dataRow = new object[reader.FieldCount];

while (reader.Read()) { int cols = reader.GetValues(dataRow); for (int i = 0; i < cols; i++) Console.Write("| {0} " , dataRow[i]);

Console.WriteLine();}

• Read and process data rows

//----- close readerreader.Close();} catch (Exception e) {

Console.WriteLine(e.Message);} finally {

try { if (con != null)

// ----- close connection con.Close();

} catch (Exception ex) { Console.WriteLine(ex.Message); }}

}}

• Close connection

Page 17: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

17

Interface IDbConnection<<interface>>

IDbConnection

Transaction 1

/ / - - - - - Pr oper t i esstri ng Connect i onStri ng

{get ; set ; }stri ng Database {get ; }i nt Connect i onTi meout {get ; }Connect i onSt at e State {get ; }

/ / - - - - - Met hodsI DbTr ansact i onBegi nTransact i on( ) ;I DbTr ansact i on Begi nTransact i on

( I sol at i onLevel l vl ) ;

I DbCommand CreateCommand( ) ;

voi d Cl ose( ) ;voi d Open( ) ;

...

publ i c enum Connect i onState { Br oken, Cl osed, Connect i ng, Execut i ng, Fet chi ng, Open}

• ConnectionString defines data base connection

• Open and close connection

• Properties of connection object

• Creates Command-Object

• Creates Transaction-Object

string ConnectionString {get; set;}

string Database {get;} int ConnectionTimeout {get;}ConnectionState State {get;}

IDbCommand CreateCommand();

IDbTransaction BeginTransaction();IDbTransaction BeginTransaction(IsolationLevel lvl);

void Close();void Open();

Page 18: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

18

IDbConnection: Property ConnectionString

• Key-value-pairs separated by semicolon (;)• Configuration of the connection

– name of the provider

– identification of data source

– authentication of user

– other database-specific settings

• e.g.: OLEDB:"provider=SQLOLEDB; data source=127.0.0.1\\NetSDK;

initial catalog=Northwind; user id=sa; password=; "

"provider=Microsoft.Jet.OLEDB.4.0;data source=c:\bin\LocalAccess40.mdb;"

"provider=MSDAORA; data source=ORACLE8i7; user id=OLEDB; password=OLEDB;"

• e.g.: MS-SQL-Server:"data source=(local)\\NetSDK; initial catalog=Northwind; user id=sa;

pooling=false; Integrated Security=SSPI; connection timout=20;"

Page 19: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

19

Command Objects

• Command objects define SQL statements or stored procedures

• Executed for a connection

• May have parameters

• May belong to a transaction

IDbCommand

IDbConnection

1

IDbTransaction0..1 * IDataParameter*1

Page 20: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

20

Interface IDbCommand<<interface>>IDbCommand

Transaction 1

/ / - - - - - Pr oper t i esstri ng CommandText {get ; set ; }CommandType CommandType

{get ; set ; }i nt CommandTi meout

{get ; set ; }I DbConnect i on Connect i on

{get ; set ; }I Dat aPar amet er Col l ect i on

Parameters {get ; }I DbTr ansact i on Transact i on

{get ; set};. . .

/ / - - - - - Met hodsI DbDat aPar amet er CreateParameter ( ) ;I Dat aReader ExecuteReader ( ) ;I Dat aReader ExecuteReader

( CommandBehavi or b) ;obj ect ExecuteScal ar ( ) ;i nt ExecuteNonQuery( ) ;. . .

publ i c enum CommandType { Text , St or edPr ocedur e, Tabl eDi r ect }

• CommandText defines SQL statement or stored procedure

• Connection object

• Type and timeout properties

• Creating and accessing parameters

• Execution of command

string CommandText {get; set;}

CommandType CommandType {get; set;} int CommandTimeout {get; set;}

IDbDataParameter CreateParameter(); IDataParameterCollection Parameters {get;}

IDataReader ExecuteReader();IDataReader ExecuteReader(CommandBehavior b);object ExecuteScalar();int ExecuteNonQuery();

IDbConnection Connection {get; set;}

Page 21: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

21

cmd.CommandText = "SELECT EmployeeID, LastName, FirstName FROM Employees ";

IDataReader reader = cmd.ExecuteReader();

• Executes the data base query specified in CommandText• Result is an IDataReader object

ExecuteReader Method

IDataReader ExecuteReader()

IDataReader ExecuteReader( CommandBehavior behavior );

public enum CommandBehavior {

CloseConnection, Default, KeyInfo, SchemaOnly,

SequentialAccess, SingleResult, SingleRow

}

Example:

Page 22: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

22

cmd.CommandText = "UPDATE Empls SET City = ’Seattle’ WHERE ID=8";int affectedRows = cmd.ExecuteNonQuery();

• Executes the non-query operation specified in CommandText – UPDATE– INSERT – DELETE – CREATE TABLE – …

• Result is number of affected rows

ExecuteNonQuery Method

int ExecuteNonQuery();

Example:

Page 23: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

23

cmd.CommandText = " SELECT count(*) FROM Employees ";int count = (int) cmd.ExecuteScalar();

• Returns the value of the 1st column of the 1st row delivered by the database query

• CommandText typically is an aggregate function

ExecuteScalar Method

object ExecuteScalar();

Example:

Page 24: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

24

Parameter

• Command objects allow for input and output parameters

• Parameter objects specify– Name: name of the parameter

– Value: value of the parameter

– DbDataType: data type of the parameter

– Direction: direction of the parameter• Input • Output • InputOutput• ReturnValue

<<interface>>IDbCommand

<<interface>>IDataParameter

<<interface>>IDbDataParameter

//----- PropertiesDbType DbType {get; set;}ParameterDirection Direction {get; set;}string ParamterName {get; set;}object Value {get; set;}...

//----- Propertiesint Size {get; set;}...

Parameters *

...IDataParameterCollection

Parameters {get;}...IDataParameterCollection Parameters {get;}

Page 25: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

25

Working with Parameters

2. Create and add parametercmd.Parameters.Add( new OleDbParameter("@ID", OleDbType.BigInt));

3. Assign values and execute command

cmd.Parameters["@ID"].Value = 1234;cmd.ExecuteNonQuery();

SqlCommand cmd = new SqlCommand(); cmd.CommandText = "DELETE FROM Empls WHERE EmployeeID = @ID";

1. Define SQL command with place holdersOLEDB: Identification of parameters by position (notation: "?")

SQL Server: Identification of parameters by name (notation: "@name")

OleDbCommand cmd = new OleDbCommand();cmd.CommandText = "DELETE FROM Empls WHERE EmployeeID = ?";

Page 26: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

26

Transactions

• ADO.NET supports transactions

• Commands are assigned to transactions

• Execution of commands are– committed with Commit– aborted with Rollback

<<interface>>IDbCommand

<<interface>>IDbTransaction

<<interface>>IDbConnection

//----- PropertiesIDbConnection Connection {get;}IsolationLevel IsolationLevel {get;}// Methodsvoid Commit();void Rollback();...

Transaction 1

...IDbTransaction Transaction {get; set;}...

Connection 1

…IDbTransaction BeginTransaction();IDbTransaction BeginTransaction (IsolationLevel lvl);

Page 27: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

27

Working with Transactions (1)

2. Create Command object, assign it to Transaction object, and execute it

IDbCommand cmd1 = con.CreateCommand(); cmd1.CommandText = "DELETE [OrderDetails] WHERE OrderId = 10258"; cmd1.Transaction = trans; cmd1.ExecuteNonQuery();

IDbCommand cmd2 = con.CreateCommand(); cmd2.CommandText = "DELETE Orders WHERE OrderId = 10258"; cmd2.Transaction = trans; cmd2.ExecuteNonQuery();

SqlConnection con = new SqlConnection(connStr);IDbTranaction trans = null; try { con.Open(); trans = con.BeginTransaction(IsolationLevel.ReadCommitted);

1. Define connection and create Transaction object

Page 28: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

28

Working with Transactions (2)

trans.Commit(); catch (Exception e) {

if (trans != null) trans.Rollback(); } finally { try { con.Close(); }}

3. Commit or abort transaction

Page 29: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

29

Isolation Levels for Transactions

• Define usage of read and write locks in transaction

• ADO.NET transactions allow different isolation levels

ReadUncommitted • Allows reading of locked data• Dirty reads possible

ReadCommitted (Standard)

• Reading of locked data prohibited• No dirty reads but phantom rows can occur • Non-repeatable reads

RepeatableRead • Same as ReadCommitted but repeatable reads

Seriazable • Serialized access• Phantom rows cannot occur

public enum IsolationLevel {ReadUncommitted, ReadCommitted, RepeatableRead, Serializable, ...

}

Page 30: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

30

DataReader

• ExecuteReader() returns DataReader object

• DataReader allows sequential reading of result (row by row)

IDataReader ExecuteReader()

IDataReader ExecuteReader( CommandBehavior behavior );

bool Read()A B C

Result table of a SELECT statementResult table of a SELECT statement

Page 31: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

31

Interface IDataReader<<interface>>IDataRecord

<<interface>>IDataReader

Transaction 1

//----- Propertiesint FieldCount {get;}object this[int] {get;}object this[string] {get;}

//----- Access Methodsbool GetBoolean(int idx);byte GetByte(int idx);string GetDataTypeName(int i);string GetName(int idx);int GetOrdinal(string name);int GetValues(object[] values);bool IsDBNull(int idx);...

//----- Propertiesbool IsClosed {get;}...//----- Methodenvoid Close();bool Read();...

• Read reads next row

• Access to column values using indexers

• Typed access to column values using access methods

• Getting meta information

bool Read();

object this[int] {get;}object this[string] {get;}

bool GetBoolean(int idx);byte GetByte(int idx);...

string GetDataTypeName(int i);string GetName(int idx);int GetOrdinal(string name);...

Page 32: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

32

Working with IDataReader

object[ ] dataRow = new object[reader.FieldCount];int cols = reader.GetValues(dataRow);

• Read column values into an array

object val0 = reader[0]; object nameVal = reader["LastName"];

• Read column values using indexers

string firstName = reader.getString(2);

• Read column value using typed access method getString

}reader.Close();

• Close DataReader

IDataReader reader = cmd.ExecuteReader();while (reader.Read()) {

• Create DataReader object and read rows

Page 33: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

ADO.NETIntroduction

Connection-oriented Access

Connectionless Access

Database Access with DataAdapter

Integration with XML

Preview of ADO.NET 2.0

Summary

Page 34: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

34

Motivation and Idea

• Motivation– Many parallel, long lasting access operations

– Connection-oriented data access too costly

• Idea – Caching data in main memory

“main memory data base“

– Only short connections for reading and updates

DataAdapter

– Main memory data base independent from data source

conflicting changes are possible

Page 35: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

35

Microsoft 3-Tier Architecture

taken from: Introduction to Data Access with ADO.NET, http://msdn.microsoft.com/library/

Page 36: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

36

Architecture of Connectionless Data Access

ADO.NET Content Components

XML file

DataSet

Tables

Relations

DataTable

ReadXmlWriteXml

DataTable

Constraints

DataColumn

DataRow

DataRelation

connection-oriented connectionless

ADO.NET ManagedProviders

Database

Update

Fill

Connectionless data flow Connection-oriented data flow

DataAdapter

Page 37: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

37

DataSet

• Main memory data base– relational structure

– object oriented interface

• DataSet consists of– collection of DataTables

– collection of DataRelations

• DataTables consists of– collection of DataTableColumns (= schema definition)

– collection of DataTableRows (= data)

– DefaultView (DataTableView, see later)

• DataRelations– associate two DataTable objects

– define ParentTable and ParentColumns and ChildTable and ChildColumns

Page 38: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

38

DataSet

.Tables[...]

.Relations[...]

...

DataSet Structure

DataTable

.Columns[..]

.Rows[..]

DataTable

.Columns[...]

.Rows[...]

.DefaultView

...

DataRow

DataRowdata

DataColumn

schema

DataColumn

DataView

DataRelationDataRelation

Page 39: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

39

DataSet Class Diagram

DataSet

Transaction 1

//----- Propertiesstring DataSetName {get; set;}DataRelationsCollection Relations {get;}DataTableCollection Tables {get;}PropertyCollection ExtendedProperties {get;}string NameSpace {get;}bool HasErrors {get;}

...

DataTable

//----- Propertiesstring TableName {get;}DataRelationsCollection ChildRelations {get;}DataRelationsCollection ParentRelations {get;}ConstraintCollection Constraints {get;}DataColumnCollection Columns {get;}DataView DefaultView {get;}bool HasErrors {get;}DataColumn[] PrimaryKey{get; set;}DataRowCollection Rows {get;}...

* Tables

DataRow

//----- Propertiesstring DataSetName {get; set;}DataRelationsCollection Relations {get;}DataTableCollection Tables {get;}PropertyCollection ExtendedProperties {get;}string NameSpace {get;}bool HasErrors {get;}

...

*Rows

DataRelation

//----- Propertiesstring RelationName {get; set;}DataTable ParentTable {get;}DataColumn[] ParentColumns {get;}DataTable ChildTable {get;}DataColumn[] ChildColumns {get;}...

Relations*

ParentRelations*

ChildRelations*

*ParentColumns

*ChildColumns

DataColumn

//----- Propertiesbool AllowDBNull {get; set;}bool AutoIncrement {get; set;}int AutoIncrementSeed {get; set;}int AutoIncrementStep {get; set;}string ColumnName {get; set;}Type DataType {get; set;}string Expression {get; set;}bool ReadOnly {get; set;}bool Unique {get; set;}...

Columns*

Page 40: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

40

Realisation as data set

DataSet

Example: Person Contacts

Implementation steps: • Define schema• Define data• Access data

Person

ID

FirstName

Name

Contact

ID

FirstName

Name

NickName

Phone

EMail

PersonID

Concept

Data

Re

lation„P

ersonH

asCo

ntacts“

DataTable „Person“

DataColumn „ID“

DataColumn „FirstName“

DataColumn „Name“

DataTable „Contact“

DataColumn „ID“

DataColumn „FirstName“

DataColumn „Name“

DataColumn „NickName“

DataColumn „EMail“

DataColumn „Phone“

DataColumn „PersonID“

Page 41: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

41

Person Contacts: Define Schema (1)

DataColumn col = new DataColumn(); col.DataType = typeof(System.Int64); col.ColumnName = "ID"; col.ReadOnly = true; col.Unique = true; // values must be unique col.AutoIncrement = true; // keys are assigned automatically col.AutoIncrementSeed = -1; // first key starts with -1 col.AutoIncrementStep = -1; // next key = prev. key - 1

• Define column "ID" and set properties

personTable.Columns.Add(col); personTable.PrimaryKey = new DataColumn[ ] { col };

• Add column to table and set as primary key

DataSet ds = new DataSet("PersonContacts"); DataTable personTable = new DataTable("Person");

• Create DataSet and DataTable "Person"

Page 42: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

42

Person Contacts: Define Schema (2)

col = new DataColumn(); col.DataType = typeof(string); col.ColumnName = "FirstName"; personTable.Columns.Add(col);

• Define and add column "FirstName"

col = new DataColumn(); col.DataType = typeof(string); col.ColumnName = "Name"; personTable.Columns.Add(col);

• Define and add column "Name"

ds.Tables.Add(personTable);

• Add table to DataSet

DataTable contactTable = new DataTable("Contact"); ...ds.Tables.Add(contactTable);

• Create table "Contact" in similar way

Page 43: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

43

Person Contacts: Define Relation

DataColumn parentCol = ds.Tables["Person"].Columns["ID"]; DataColumn childCol = ds.Tables["Contact"].Columns["PersonID"];

DataRelation rel = new DataRelation("PersonHasContacts", parentCol, childCol); ds.Relations.Add(rel);

• Create relation PersonHasContacts• and add it to the DataSet

DataTable „Person“ DataTable „Contact“

DataColumn „ID“

DataColumn „FirstName“

DataColumn „Name“

DataColumn „NickName“

DataColumn „EMail“

DataColumn „Phone“

DataColumn „PersonID“

DataColumn „ID“

DataColumn „FirstName“

DataColumn „Name“

Da

taR

ela

tion

„Pe

rson

Ha

sCo

nta

cts“

Page 44: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

44

Person Contacts: Define Data Rows

DataRow personRow = personTable.NewRow(); personRow[1] = "Wolfgang"; personRow["Name"] = "Beer";

• Create new row and assign column values

• Add row to table "Person"

personTable.Rows.Add(row);

• Commit changes

ds.AcceptChanges();

• Create and add row to table "Contact"

DataRow contactRow = contactTable.NewRow (); contactRow[0] = "Wolfgang"; ...contactRow["PersonID"] = (long)personRow["ID"]; // defines relation contactTable.Rows.Add (row);

Page 45: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

45

Person Contacts: Access Data

foreach (DataRow person in personTable.Rows) { Console.WriteLine("Contacts of {0}:", person["Name"]);

• Iterate over all persons of personTable and put out the names

• Access contacts through relation "PersonHasContacts" and print out contacts

foreach (DataRow contact in person.GetChildRows("PersonHasContacts")) { Console.WriteLine("{0}, {1}: {2}", contact[0], contact["Name"], contact["Phone"] );

}

Page 46: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

46

DataSet: Change Management

• DataSets maintain all changes

• Changes are accepted with acceptChanges• or discarded with rejectChanges

...if (ds.HasErrors) {

ds.RejectChanges(); } else {

ds.AcceptChanges();}

}

Page 47: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

47

State Diagram of a DataRow object• DataRow objects have different states

public DataRowState RowState {get;}

public enum DataRowState {Added, Deleted, Detached, Modified, Unchanged

}

Detached

Deleted

Unchanged Modified

row =table.NewRow

table.Row.Add(row) Reject-

Changesrow.Delete

Accept-Changes

row.Delete

RejectChanges

row.Delete

Accept-Changes

Accept-Changes

Reject-Changes

row[..] = ..

table.Rows.Remove(row)

Added

Page 48: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

48

DataRowVersion

DataSets store different versions of data row values:

Current: current values

Original: original values

Proposed: proposed values (values which are currently processed)

Default: standard, based on DataRowState

public enum DataRowVersion {Current, Original, Proposed, Default

}

bool hasOriginal = personRow.HasVersion(DataRowVersion.Original); if (hasOriginal) {

string originalName = personRow["Name", DataRowVersion.Original];}

Example:

DataRowState Default

Added, Modified, Unchanged Current

Deleted Original

Detached Proposed

Page 49: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

49

Exception Handling• ADO.NET checks validity of operations on DataSets

• and throws DataExceptions

DataException

ConstraintException

DeletedRowInaccessibleExcception

DuplicateNameException

InvalidConstraintException

InvalidExpressionException

MissingPrimaryKeyException

NoNullAllowedException

ReadOnlyException

RowNotInTableException

...

Page 50: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

50

DataView

• DataViews support views of tablesRowFilter: Filtering based on filter

expression

RowStateFilter: Filtering based on row states

Sort: Sorting based on columns

• DataView supports – changing data rows

– fast search (based on sorted columns)

• DataView objects can be displayed by GUI elememts

– e.g. DataGrid

DataView

//----- Propertiesbool AllowDelete {get; set;}bool AllowEdit {get; set;}bool AllowNew {get; set;}int Count {get;}DataTable Table {get;}string RowFilter {get;}DataViewRowState RowStateFilter {get; set;}string Sort {get;}DataRowView this[int] {get;}

//----- MethodsDataRowView AddNew()void Delete( int index )int Find( object key )DataRowView[] FindRows( object key )...

DataTable

DataRowView

//----- Propertiesobject this[int] {get; set;}object this[string] {get; set;}string DataSetName {get; set}DataView View {get;}DataRow Row {get;}...

DataRow

Item *

Rows *

Row1

Table1

Page 51: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

51

Working with DataView

• Fast search for row based on "Name" column

int i = a_kView.Find("Beer");grid.Select(i);

DataView a_kView = new DataView(personTable);dataView.RowFilter = "FirstName <= 'K'"; dataView.RowStateFilter =

DataViewRowState.Added | DataViewRowState.ModifiedCurrent;dataView.Sort = "Name ASC"; // sort by Name in ascending order

• Create DataView object and set filter and sorting criteria

• Display data in DataGrid

DataGrid grid = new DataGrid(); ...grid.DataSource = dataView;

Page 52: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

ADO.NETIntroduction

Connection-oriented Access

Connectionless Access

Database Access with DataAdapter

Integration with XML

Preview of ADO.NET 2.0

Summary

Page 53: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

53

Architecture

connection-oriented connectionless• DataAdapter for connection to

date sourceFill: Filling the DataSet

Update: Writing back changes

• DataAdapters use Command objects

SelectCommand

InsertCommand

DeleteCommand

UpdateCommand

ADO.NET ContentComponents

Database

XML file

Verbindungsloser Datenfluss Verbindungsorientierter Datenfluss

DataSet

ReadXmlWriteXml

ADO.NET ManagedProviders

DataAdapter

IDbConnection

Update

Fill

DeleteCommand

UpdateCommand

InsertCommand

SelectCommand

Page 54: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

54

DataAdapter Class Diagram<<interface>>IDataAdapter

//----- PropertiesMissingSchemaAction MissingSchemaAction {get; set;}MissingMappingAction MissingMappingAction {get; set;}ITableMappingCollection TableMappings {get;}//----- Methodsint Fill (DataSet ds);int Update (DataSet ds);...

<<interface>>IDbDataAdapter

//----- PropertiesIDbCommand SelectCommand {get; set;}IDbCommand InsertCommand {get; set;}IDbCommand DeleteCommand {get; set;}IDbCommand UpdateCommand {get; set;}...

DataAdapter

DbDataAdapter

//----- Merthodsint Fill (DataSet dt);int Fill (DataTable dt);int Fill (DataSet ds, string table);int Fill (DataSet ds, int start, int end, string table);int Update (DataSet ds);int Update (DataTable dt);int Update (DataSet ds, string table);int Update (DataRow[] rows);...

OleDbDataAdapter SqlDataAdapter OracleDataAdapter

...

Page 55: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

55

DataAdapter: Loading Data

IDbDataAdapter adapter = new OleDbDataAdapter(); OleDbCommand cmd = new OleDbCommand(); cmd.Connection = new OleDbConnection ("provider=SQLOLEDB; ..." ); cmd.CommandText = "SELECT * FROM Person"; adapter.SelectCommand = cmd;

• Create DataAdapter object and set SelectCommand

• Read data from data source and fill DataTable "Person"

adapter.Fill(ds, "Person");

• Accept or discard changes

• Delete DataAdapter object

if (ds.HasErrors) ds.RejectChanges(); else ds.AcceptChanges(); if (adapter is IDisposable) ((IDisposable)adapter).Dispose();

Page 56: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

56

DataAdapter: Loading Schema and Data

IDbDataAdapter adapter = new OleDbDataAdapter(); OleDbCommand cmd = new OleDbCommand(); cmd.Connection = new OleDbConnection ("provider=SQLOLEDB; ..." ); cmd.CommandText = "SELECT * FROM Person; SELECT * FROM Contact"; adapter.SelectCommand = cmd;

• Create DataAdapter object and set SelectCommand

• Read data from data source and fill DataTable "Person"

adapter.Fill(ds);

• Accept or discard changes; delete DataAdapter object

if (ds.HasErrors) ds.RejectChanges(); else ds.AcceptChanges(); if (adapter is IDisposable) ((IDisposable)adapter).Dispose();

• Define action for missing schema and mapping to tables

adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey; adapter.TableMappings.Add("Table", "Person"); adapter.TableMappings.Add("Table1", "Contact");

Page 57: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

57

DataAdapter: Writing Back Changes (1)

• Changes are written back with Update method

• Update-, Insert- and DeleteCommand define how changes are written

• CommandBuilder can create Update-, Insert- und DeleteCommand from SelectCommand automatically (in simple cases )

• Conflict management for updates:

– comparison of data in DataTable and data source

– in case of conflict DBConcurrencyException is thrown

Page 58: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

58

DataAdapter: Writing Back Changes (2)

OleDbConnection con = new OleDbConnection ("provider=SQLOLEDB; …"); adapter = new OleDbDataAdapter("SELECT * FROM Person", con);

• Create DataAdapter with SELECT expression

• Create update commands using CommandBuilder

OleDbCommandBuilder cmdBuilder = new OleDbCommandBuilder(adapter);

• Call Update and handle conflicts

try { adapter.Update(ds, tableName);

} catch (DBConcurrencyException) { // Handle the error, e.g. by reloading the DataSet

} adapter.Dispose();

Page 59: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

59

DataAdapter: Event Handling

• Two events signaled on updates for each data row– OnRowUpdating: just before updating the data source

– OnRowUpdated: just after updating the data source

public sealed class OleDbDataAdapter : DbDataAdapter, IDbDataAdapter{

public event OleDbRowUpdatingEventHandler RowUpdating; public event OleDbRowUpdatedEventHandler RowUpdated; …

}

public delegate void OleDbRowUpdatedEventHandler( object sender, OleDbRowUpdatedEventArgs e );

public sealed class OleDbRowUpdatedEventArgs : RowUpdatedEventArgs {public DataRow Row {get;} public StatementType StatementType {get;} public UpdateStatus Status {get; set;} …

}

Page 60: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

60

DataAdapter: Event Handling Example

OleDbDataAdapter adapter = new OleDbDataAdapter(); ...da.RowUpdating += new OleDbRowUpdatingEventHandler(this.OnRowUpdating);da.RowUpdated += new OleDbRowUpdatingEventHandler(this.OnRowUpdated);

• Add delegates to events of DataAdapter

• Define handler methods

private void onRowUpdating(object sender, OleDbRowUpdatedEventArgs args) {Console.WriteLn("Updating row for {0}", args.Row[1]); ...

}

private void onRowUpdated(object sender, OleDbRowUpdatedEventArgs args) {...

}

Page 61: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

ADO.NETIntroduction

Connection-oriented Access

Connectionless Access

Database Access with DataAdapter

Integration with XML

Preview of ADO.NET 2.0

Summary

Page 62: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

62

Integration DataSets und XML

• DataSets and XML are highly integrated

– serializing DataSets as XML data

– XML documents as data sources for DataSets

– schemas for DataSets defined as XML schemas

– strongly typed DataSets generated from XML schemas

– access to DataSets using XML-DOM interface

• Integration of DataSets and XML used in distributed systems, e.g., web services

– (see Microsoft 3-Tier Architecture)

Page 63: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

63

Writing and Reading XML Data• Methods for writing and reading XML data

public class DataSet : MarshalByValueComponent, IListSource, ISupportInitialize, ISerializable {

public void WriteXml( Stream stream );public void WriteXml( string fileName );public void WriteXml( TextWriter writer);public void WriteXml( XmlWriter writer );public void WriteXml( Stream stream, XmlWriteMode m );public void ReadXml ( Stream stream );public void ReadXml ( string fileName );public void ReadXml ( TextWriter writer);public void ReadXml ( XmlWriter writer );public void ReadXml ( Stream stream, XmlReadMode m );...

}

public enum XmlWriteMode {DiffGram, IgnoreSchema, WriteSchema}

public enum XmlReadMode {Auto, DiffGram, IgnoreSchema, ReadSchema, InferSchema, Fragment }

Page 64: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

64

Example: Writing and Reading XML Data <?xml version="1.0" standalone="yes" ?> <PersonContacts>- <Person>  <ID>1</ID>   <FirstName>Wolfgang</FirstName>   <Name>Beer</Name>

</Person>- <Person>  <ID>2</ID>   <FirstName>Dietrich</FirstName>   <Name>Birngruber</Name>   </Person>

<Contact><ID>1</ID>

  <FirstName>Dietrich</FirstName>   <Name>Birngruber</Name>   <NickName>Didi</NickName>   <EMail>[email protected]</EMail>   <Phone>7133</Phone>   <PersonID>2</PersonID>   </Contact>- <Contact>  <ID>2</ID>   <FirstName>Wolfgang</FirstName>   <Name>Beer</Name>

...  <PersonID>1</PersonID>   </Contact>  </PersonContacts>

ds.writeXML("personcontact.xml");

• Write data to XML file

DataSet ds = new DataSet(); ds.readXML("personcontact.xml",

XmlReadMode.Auto);

• Read data from XML– with XmlReadMode.Auto a schema is generated automatically

Page 65: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

65

DataSet and XML Schema• DataSets allow reading and writing XML schemas

– WriteXmlSchema: Writes XML schema

– ReadXmlSchema: Reads XML schema and constructs DataSet

– InferXmlSchema: Reads XML data and infers schema from the data

...public void WriteXmlSchema ( Stream stream );public void WriteXmlSchema ( string fileName );public void WriteXmlSchema ( TextWriter writer);public void WriteXmlSchema ( XmlWriter writer );

public void ReadXmlSchema ( Stream stream );public void ReadXmlSchema ( string fileName );public void ReadXmlSchema ( TextWriter writer);public void ReadXmlSchema ( XmlWriter writer );

public void InferXmlSchema ( Stream stream, string[] namespaces );public void InferXmlSchema ( string fileName, string[] namespaces );public void InferXmlSchema ( TextWriter writer, string[] namespaces );public void InferXmlSchema ( XmlWriter writer, string[] namespaces );

}

Page 66: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

66

Typed DataSets

• Typed DataSets provide typed data access

• Tool xsd.exe generates classes from XML schema

• Classes define properties for typed access to rows, columns, and relations

> xsd.exe personcontact.xsd /dataset

DataTable

DataRow

Rows *

DataSet

Tables *

PersonContacts

PersonDataTable Person {get;}ContactDataTable Contact {get;}...

PersonDataTable

PersonDataRow this[int] {get;}PersonDataRow NewPersonRow ();AddPersonRow (PersonDataRow row);...

Person 1

ContactDataTable

Contact 1

PersonRow

//----- Propertieslong id {get; set;}string FirstName {get; set;}string Name {get; set;}ContactRow[] GetContactRows()...

*

ContactRow

*

GetContact *Rows()

Page 67: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

67

Example Typed DataSets

• Data access in conventional DataSet

• Data access in typed DataSet

DataSet ds = new DataSet("PersonContacts"); DataTable personTable = new DataTable("Person"); ...ds.Tables.Add(personTable);DataRow person = personTable.NewRow(); personTable.Rows.Add(person); person["Name"] = "Beer"; ... person.GetChildRows("PersonHasContacts")[0]["Name"] = "Beer";

PersonContacts typedDS = new PersonContacts(); PersonTable personTable = typedDS.Person; Person person = personTable.NewPersonRow(); personTable.AddPersonRow(person); person.Name = "Beer"; ...person.GetContactRows()[0].Name = "Beer";

Page 68: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

68

Access to DataSets using XML-DOM

• XmlDataDocument allows access over XML-DOM interface

• Synchronisation of changes in XmlDataDocument and DataSet

XmlDataDocument xmlDoc = new XmlDataDocument(ds); ...DataTable table = ds.Tables["Person"]; table.Rows.Find(3)["Name"] = "Changed Name!";

Example: • Create XmlDataDocument object for DataSet objekt• Change data in DataSet

XmlElement root = xmlDoc.DocumentElement; XmlNode person = root.SelectSingleNode("descendant::Person[ID='3']"); Console.WriteLine("Access via XML: \n" + person.OuterXml);

• Access changed data from XmlDataDocument object

Page 69: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

ADO.NETIntroduction

Connection-oriented Access

Connectionless Access

Database Access with DataAdapter

Integration with XML

Preview of ADO.NET 2.0

Summary

Page 70: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

70

ADO.NET 2.0

• Extended interfaces

• Tight coupling with MS SQL Server 9.0 („Yukon“)

New features are (many only available for MS SQL Server 9.0):– bulk copy operation

– Multiple Active Result Sets (MARS)

– asynchronous execution of database operations

– batch processing of database updates

– paging through the result of a query

– ObjectSpaces

Page 71: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

71

Bulk Copy Operation• Inserting a large amount of data in one operation (only for MS SQL

Server)

• Provided by class SqlBulkCopyOperation

SqlConnection sourceCon = new SqlConnection(conString); sourceCon.Open();SqlCommand sourceCmd = new SqlCommand("SELECT * FROM Customers",sourceCon);IDataReader sourceReader = sourceCmd.ExecuteReader();

1. Define data source

SqlConnection targetCon = new SqlConnection(conString); targetCon.Open();

2. Define target

SqlBulkCopyOperation bulkCmd = new SqlBulkCopyOperation(targetCon);bulkCmd.DestinationTableName = "Copy_Customers";bulkCmd.WriteDataReaderToServer(sourceReader);

3. Copy data from source to target in one operation

Example

Page 72: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

72

Multiple Active Result Sets (MARS)

• So far only one DataReader for one connection allowed

• ADO.NET 2.0 allows several DataReaders in parallel

SqlConnection con = new SqlConnection(conStr);con.Open();SqlCommand custCmd = new SqlCommand("SELECT CustomerId, CompanyName " +

"FROM Customers ORDER BY CustomerId", con);SqlCommand ordCmd = new SqlCommand("SELECT CustomerId, OrderId, OrderDate " +

"FROM Orders ORDER BY CustomerId, OrderDate", con);SqlDataReader custRdr = custCmd.ExecuteReader();SqlDataReader ordRdr = ordCmd.ExecuteReader();string custID = null;while (custRdr.Read()) { // use the first reader

custID = custRdr.GetString(0);while (ordRdr.Read() && ordRdr.GetString(0) == custID ) { // use the second reader

...}

}…

Page 73: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

73

Asynchronous Operations

• So far only synchronous execution of commands

• ADO.NET 2.0 supports asynchronous execution mode (similar to asynchronous IO operations)

IAsyncResult BeginExecuteReader (AsyncCallback callback)IDataReader EndExecuteReader (AsyncResult result)

IAsyncResult BeginExecuteNonQuery (AsyncCallback callback)int EndExecuteNonQuery (IAsyncResult result)

IAsyncResult BeginExecuteXmlReader (AsyncCallback callback)IDataReader EndExecuteXmlReader (IAsyncResult result)

Page 74: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

74

Example Asynchronous Operations

...public class Async {

SqlCommand cmd; // command to be executed asynchronouslypublic void CallCmdAsync() {

SqlConnection con = new SqlConnection("Data Source=(local)\\NetSDK...");cmd = new SqlCommand("MyLongRunningStoredProc", con);cmd.CommandType = CommandType.StoredProcedure;con.Open();// execute the command asynchronouslycmd.BeginExecuteNonQuery(new AsyncCallback(AsyncCmdEnded), null);

... }

// this callback method is executed when the SQL command is finishedpublic void AsyncCmdEnded(IAsyncResult result) {

cmd.EndExecuteNonQuery(result); // optionally do some work based on results...

}}

Page 75: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

75

Batch Processing of Database Updates

• So far rows are updated individually

• With ADO.NET 2.0 several rows can be updated in one batch (only available for MS SQL Server)

• UpdateBatchSize can be specified for DataAdapter

void UpdateCategories(DataSet ds, SqlConnection con) {// create an adapter with select and update commandsSqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Categories", con);// the command builder creates the missing UPDATE, INSERT and DELETE commandsSqlCommandBuilder cb = new SqlCommandBuilder(da);// set the batch size != 1da.UpdateBatchSize = 50;… // execute the update in batch modeda.Update(ds.Tables["Categories"] );

}

Page 76: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

76

Paging

• Operation ExecutePageReader allows accessing a subset of rows

Very useful in combination with user interface controls (e.g. DataGrid)

ExecutePageReader(CommandBehavior b, int startRow, int pageSize)

Page 77: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

77

ObjectSpaces

• ObjectSpaces allow mapping of objects and relational data

• Mapping defined in language OPath which (based on XPath)

Classes of ObjectSpaces

ObjectSpace: for communication with the data source

ObjectSources: list of connections to the data source

ObjectQuery: for reading objects with OPath

ObjectSet: stores the objets (similar to DataSet)

ObjectList and ObjectHolder: collections for delayed reading of objects

Page 78: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

78

Example ObjectSpacespublic class Customer { // mapped class

public string Id; // primary keypublic string Name;public string Company;public string Phone;

}public class ObjectSpaceSample {

public static void Main() {// load the mapping and data source information and create the ObjectSpace.

SqlConnection con = new SqlConnection("Data Source=(local)\\NetSDK; ...");ObjectSpace os = new ObjectSpace("map.xml", con);// query for objects ObjectQuery oQuery = new ObjectQuery(typeof(Customer),"Id >= 'T'", "");ObjectReader reader = os.GetObjectReader(oQuery);// print resultforeach (Customer c in reader) {

Console.WriteLine(c.GetType() + ":");Console.WriteLine("Id: " + c.Id);Console.WriteLine("Name: " + c.Name);Console.WriteLine("Phone: " + c.Phone);

} reader.Close();

con.Close();}

}

Page 79: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

ADO.NETIntroduction

Connection-oriented Access

Connectionless Access

Database Access with DataAdapter

Integration with XML

Preview of ADO.NET 2.0

Summary

Page 80: Data Access with ADO.NET Dr. Herbert Praehofer Institute for System Software Johannes Kepler University Linz Dr. Dietrich Birngruber Software Architect.

80

Summary

• Connection-oriented data access model– for applications with only a few parallel, short running transactions

– object-oriented interface abstracts from data source

– access to database by SQL commands

• Connectionless data access model– for applications with many parallel, long running transactions

– DataSet as main memory data base

– DataAdapter is used as connector to the data source

– tight integration with XML

– well integrated in the .NET Framework (e.g.: WebForms, WinForms)