3 ADO NET

background image

Warstwa dostępu do danych

Mainframe

Directory

RDBMS

Email i
wiadomo

ści

System plik

ów

ADO

OLE DB

XML

Problemy

Modele programistyczne

Połączeniowy (connected) – oparcie o otwarte

połączenia do systemu bazy danych (OLE DB, ADODB)

Bezpołączeniowy (disconnected) – pytanie/odpowiedź,

bez-

stanowy między zapytaniami (HTTP)

Obsługa stanu

• Architektura ADO.NET

• Obiekty DataSet, Connection, Command, DataAdapter i ich

współdziałanie

• Praca w trybie połączonym: DataReader
• Praca w trybie odłączonym: DataSet
• Modyfikacje źródła danych
• Obsługa procedur pamiętanych w b.d.
• Integracja z XML
• Transakcje

LINQ, Entity Framework
ADO.NET Data Services

background image

Tryb połączeniowy

• W modelu klient – serwer każdy klient łączy się z bazą podczas startu

aplikacji i zwalnia połączenie podczas jej zamykania

• Serwer musi utrzymywad oddzielne połączenia dla każego klienta

Klienci

Połączenia

Serwer

busy

idle

idle

Możliwe niepotrzebne zużycie

zasobów

Tabele

Wyniki zapytania

Kursor

rs

Klient

Serwer

Serwery bazodanowe zapewniają

dostęp do kursora

przechowującego stan aktualnego
wiersza

Dostęp do danych
Przesuwanie się przez MoveNext

oraz MovePrevious

background image

Tryb połączeniowy

Połączenie tworzymy tylko raz
Możemy ustawiać zmienne

powiązane z „sesją‟

Szeroki dostęp do mechanizmów

zabezpieczajacych dostarczonych
przez bazę danych

Pierwszy wiersz zapytania dostępny

od razu

Niepotrzebne zużycie zasobów
Problemy ze skalowalnością

Nie dostosowany do aplikacji webowych

Użytkownicy się nie wylogowują
Wahająca się liczba użytkowników

Nie dostosowany do aplikacji

wielowarstwowych

Zalety

Wady

background image

Tryb bezpołączeniowy

Połączenia są zwalniane zaraz po wykorzystaniu

Obiekty danych wykorzystywane są również po zwolnieniu połączenia

Połączenie jest nawiązywane by zapisad zmiany do bazy

Klienci

Połączenia

Serwer

busy

idle

idle

Zasoby są używane tylko gdy są

potrzebne

Dane są dostarczane do klienta w

jednej operacji

Wyniki zapytania przechowywane w

pamięci klienta

Zasoby serwera są zwalniane
Klient zarządza danymi w trybie off-

line

Ponowne połączenie z bazą by

zapisać zmiany

Wyniki zapytania

Kursor

Klient

rs

Serwer

Tabele

background image

Tryb bezpołączeniowy

Mniejsze zużycie zasobów serwera
Modyfikacja danych jest szybsza i

bardziej elastyczna

Dane nie związane z połączeniem
Łatwe przekazywanie między

warstwami

Wykorzystywane w aplikacjach

wielowarstwowych oraz webowych

Otwieranie i zamykanie połączeń

jest kosztowne

Wczytywanie dużych ilości danych

jest czasochłonne

Zużycie zasobów po stronie klienta
Mniej opcji zarządzania

bezpieczeńswem

Zalety

Wady

background image

Architektura ADO.NET

Database

DataSet

Tables

DataTable

DataRowCollection

DataColumnCollection

ConstraintCollection

DataRelationCollection

XML

.NET Data Provider

Connection

Transaction

Command

Parameters

DataReader

DataAdapter

SelectCommand

InsertCommand

UpdateCommand

DeleteCommand

ReadXml
WriteXml

Update

Fill

.NET data provider

jest to zestaw klas, za pomocą których podłaczamy się do źródła danych

oraz pobieramy i aktualizujemy dane

background image

ADO.NET Object Model

Klasa

Opis

Connection

Umożliwia nawiązanie

połączenia

z określonym źródłem danych

Command

Wywołuje

polecenie

na źródle danych. Udostępnia kolekcję parametrów (Parameters) i zawsze

działa w kontekście otwartego połączenia (Connection)

DataReader

Udostępnia jednokierunkowy (rekord po rekordzie) strumień danych ze źródła, w trybie 'tylko do
odczytu'

DataAdapter

Wypełnia DataSet danymi pochodzącymi ze źródła oraz umożliwia aktualizacje danych w źródle na
podstawie DataSet-

u (kanał łączący obiekt DataSet z dostawcą danych)

Connection

Command

Parameter

DataReader

Transaction

DataAdapter

DataSet

DataTable

DataColumn

DataRow

Constraint

DataRelation

.NET Data
Provider

background image

ADO.NET Class hierarchy

IDbConnection

IDbCommand

IDbTransaction

IDataReader

Interfejsy

IDbConnection
IDbCommand
IDbTransaction
IDataReader

Abstrakcyjne klasy bazowe

DbConnection
DbCommand
DbTransaction
DbDataReader


Implementacja specjalizowana

OleDb: implementacja dla OLEDB
Sql:

implementacja dla SQL
Server

Oracle: implementacja dla Oracle
Odbc: implementacja dla ODBC

DbConnection

DbCommand

DbTransaction

DbDataReader

OleDbConnection

SqlConnection

OracleConnection

...

OleDbCommand

SqlCommand

OracleCommand

OleDbTransaction

SqlTransaction

OracleTransaction

OleDbDataReader

SqlDataReader

OracleDataReader

background image

Tworzenie połączenia

SqlConnection

Parametry ConnectionString

Connection timeout: dopuszczalny czas

uzyskania połączenia

Data source: nazwa instancji SQL Server lub

nazwa komputera

Initial catalog: nazwa bazy danych
Integrated security; gdy True połączenie z SQL

serwerem na podstawie tożsamości konta procesu
ASP.NET

User ID: konto logowania SQL Server
Password:

string

strConn

= "data source=localhost; " +

"initial catalog=northwind; integrated security=true";
SqlConnection

conn

= new SqlConnection(

strConn

);

http://www.connectionstrings.com

/

Łańcuch połączenia (ang. connection string) - ciąg znaków zawierających

parametry konfiguracji połączenia

background image

Połączenie: Tworzenie połączenia

public

interface

IDbConnection

{

string

ConnectionString {

get

;

set

;}

int

ConnectionTimeout {

get

;}

string

Database {

get

;}

ConnectionState State {

get

;}

IDbTransaction BeginTransaction();

IDbTransaction BeginTransaction(IsolationLevel il);

void

ChangeDatabase(

string

db);

void

Close();

IDbCommand CreateCommand();

void

Open();

}

BeginTransaction

Rozpoczyna tranzakcję

Open, Close

– Otwieranie i zamykanie

połączenia

CreateCommand

– Tworzy obiekt Command

powiązany z połączeniem

ConnectionTimeout

– Określenie czasu timeoutu

połączenia
Database

– Nazwa bazy dla połączenia

State

– Zwraca stan aktualnego połączenia: Broken,

Closed, Connecting, Executing, Fetching, or Open.

ChangeDatabase

– Zmiana

bazy dla otrawtego połącznia

background image

ConnectionString - zarządzanie

• Umieszczamy w sekcji <connectionStrings> pliku konfiguracyjnego

< configuration >
...

< connectionStrings >

< add

name

=”

Northwind

” providerName=”System.Data.SqlClient”

connectionString=”server=(local);
integrated security=SSPI;database=Northwind” / >

< /connectionStrings

>

< /configuration >

private DbConnection

GetDatabaseConnection

( string

name

)

{
ConnectionStringSettings settings =
ConfigurationManager.ConnectionStrings[

name

];

DbProviderFactory factory =
DbProviderFactories.GetFactory(settings.ProviderName );
DbConnection

conn

= factory.CreateConnection ( ) ;

conn.ConnectionString = settings.ConnectionString ;
return

conn

;

}

background image

Wydajne używanie połączeo

try . . . catch . . . finally

try

{
// Open the connection
conn.Open();
DoSomething();
}

catch

( SqlException ex )

{
//Log the exception
}

finally

{

conn.Close ( ) ;

}

Blok using

try

{

using

(SqlConnection conn =

new SqlConnection(source))
{
// Open the connection
conn.Open ( ) ;
DoSomething();
}
}

catch

(SqlException e)

{
// Log the exception
}

using

– zapewnia wywołanie Dispose()

najwcześniej jak to możliwe, poprzez
zdeklarowanie używanych obiektów i określeniu
przez nawiasy {} zasięgu tych obiektów

background image

Pula połączeo

Connection pooling

– proces utrzymywania otwartych połączeń i

ponownego ich reużycia dla uzytkownika lub kontekstu

Parametry ConnectionString dla poolingu

Connection Lifetime: długość oczekiwania połączenia na ponowne użycie
Max Pool Size: maksymalna liczba połączeń
Min Pool Size: Minimalna liczba połączeń
Pooling: True/False

cnNorthwind.

ConnectionString

= _

"Integrated Security=True;" & _
"Initial Catalog=Northwind;" & _
"Data Source=London;" & _
"Pooling=True;" & _
"Min Pool Size=5;" & _
"Connection Lifetime=120;"

background image

ADO.NET – modele programowania

• ADO.NET zapewnia dostęp do obu typów

programowania

– Połączeniowy

• Używa obiektów

Command

i

DataReader

• DataReader

służy do odczytu w przód

• Zmiany/aktualizacje odbywają się przez obiekt

Command

– Bezpołączeniowy

• Używa obiektów

DataSet

do przechowywania danych u klienta

• DataAdapter

obsługuje komunikację miedzy obiektem

DataSet

a

serwerem

• Obiekty DataSet są niezależne od providera
• Obiekty DataSet są przechowywane oraz przesyłane przez XML

background image

Obiekt Command

Parameters

Parametry, z którymi zostanie

wykonane zapytanie

public

interface

IDbCommand

{

string

CommandText

{

get

;

set

;}

int

CommandTimeout {

get

;

set

;}

CommandType CommandType {

get

;

set

;}

IDbConnection

Connection

{

get

;

set

;}

IDbTransaction Transaction {

get

;

set

;}

UpdateRowSource UpdatedRowSource {

get

;

set

;}

IDataParameterCollection Parameters {

get

;}


void

Cancel();

IDataParameter CreateParameter();

int

ExecuteNonQuery();

IDataReader ExecuteReader();
IDataReader ExecuteReader(CommandBehavior cb);

object

ExecuteScalar();

void

Prepare();

// Note

ExecuteXmlReader (SqlCommand only)

}

Connection

- referencja do obiektu

połączenia

CommandType - typ polecenia

Text – wyrażenie SQL
StoredProcedure

CommandText

- w

zależności od

wyboru typu plecenia:

Text – treść polecenia SQL
StoredProcedure – nazwa procedury

background image

Metody wywołania obiektu Command

Zapytanie nie zwraca wierszy

– Wywołanie

ExecuteNonQuery

• Zwraca liczbę wierszy ‘dotkniętych’ przez zapytanie

– Zapytania DDL and DCL

• CREATE, ALTER, DROP, GRANT, DENY, REVOKE

– Zapytaia DML

• INSERT, UPDATE, DELETE

Zapytanie zwraca pojedynczą wartośd

– Wywołanie

ExecuteScalar

• ExecuteScalar zwraca typ Object

Zapytanie zwraca wiersz

– Metoda

ExecuteReader

• Zwraca obiekt

DataReader

• Reader zależny od providera: SqlDataReader, OleDbDataReader

– DataReader

• Służy tylko do odczytu, możliwe przesuwanie tylko w przód

Zapytanie zwraca XML

– ExecuteXmlReader

– dostępny tylko dla SQL Server

background image

Command - przykład

private

void

Demo()

{
SqlConnection

con

=

new

SqlConnection(

"Server=localhost; Database=Pubs; Integrated Security=SSPI" );
SqlCommand cmd =

new

SqlCommand(

"SELECT COUNT( * ) FROM Authors",

con

);

con

.Open();

Console.WriteLine( cmd.

ExecuteScalar

() );

// Writes '23'

con

.Close();

// Important!

}

background image

Asynchroniczne wywołanie Command

ADO.NET 2.0 wspiera tryb asynchroniczny

Wykonanie poleceń w tle

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

IAsyncResult BeginExecuteNonQuery (AsyncCallback callback)

int

EndExecuteNonQuery (IAsyncResult result)


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

background image

Asynchroniczny Command - przykład

...

public class

Async {

SqlCommand cmd;

//---- command which should be executed asynchronously

public void

CallCmdAsync() {

SqlConnection conn =

new

SqlConnection(

"Data Source=(local)\\NetSDK...; Asynchronous Processing=true"

)

;

cmd = new SqlCommand("MyLongRunningStoredProc", conn);

cmd.CommandType = CommandType.StoredProcedure;

conn.Open();

//---- start asynchronous execution of command

cmd.

BeginExecuteNonQuery

(new AsyncCallback(AsyncCmdEnded), null);

...

}

//---- callback method called at the end of the execution of command

public void

AsyncCmdEnded(IAsyncResult result) {

//---- process result of command

int

affectedRows = cmd.

EndExecuteNonQuery

(result);

...

}

}

Callback when query is finished

background image

Zapytania parametryzowane

Command pozwala na definiowanie

parametrów wejściowych i wyjściowych

Parameter - pola

Name: nazwa parametru
Value: wartość parametru
DbDataType: typ danych
Direction: kierunek parametru

- Input

- Output

- InputOutput

- ReturnValue

<<interface>>
IDbCommand

<<interface>>

IDataParameter

<<interface>>

IDbDataParameter

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

//----- Properties
int Size {get; set;}
...

Parameters

*

...
IDataParameterCollection

Parameters {get;}

...

IDataParameterCollection Parameters {

get

;}

background image

Zapytania parametryzowane - przykład

2. Dodanie parametru

cmd.Parameters.Add(

new

OleDbParameter

("@ID"

, OleDbType.BigInt));

SqlCommand cmd =

new

SqlCommand();

cmd.CommandText =

"DELETE FROM Empls WHERE EmployeeID = @ID"

;

1.

Zdefiniowanie zapytania

SQL Server:

Identyfikacja parametru przez „@”(przykład: "@name")

3.

Przypisanie wartości

cmd.Parameters[

"@ID"

].Value = 1234;

cmd.ExecuteNonQuery();

background image

Tryb połączeniowy: DataReader

Tylko do odczytu w przód
Szybki dostęp
Praca w trybie połączeniowym
Programista zarządza połączeniem i danymi
Małe zużycie zasobów

Użycie DataReader:

1.

Stwórz i otwórz połączenie

2.

Stwórz obiekt Command

3.

Stwórz DataReader dla obiektu Command

4. Odczytaj dane
5. Zamknij DataReader
6.

Zamknij połączenie

Użycie w bloku Try…Catch…Finally

public

interface

IDataReader

{

int

Depth {

get

;}

bool

IsClosed {

get

;}

int

RecordsAffected {

get

;}


void

Close();

DataTable GetSchemaTable();

bool

NextResult();

bool

Read();


}

DataReader

– Odczyt strumienia danych zwróconych przez zapytanie

NextResult -

Przejście do kolejnego zestawu wyników

Read

– Przechodzi do następnego rekordu

background image

Praca z IDataReader - przykład

object

[ ] dataRow =

new

object[reader.FieldCount];

int

cols = reader.GetValues(dataRow);

Przeczytaj kolumny do tablicy

object

val0 = reader[0];

object

nameVal = reader[

"LastName"

];

Odczyt za pomocą indekserów

string

firstName = reader.getString(2);

Odczyt za pomocą metod

}
reader.Close();

Zamknięcie obiektu

IDataReader reader = cmd.ExecuteReader();

while

(reader.Read()) {

Stwórz obiekt i rozpocznij odczyt

background image

Odczyt danych z obiektu DataReader

Wołanie Read dla każdego rekordu

Zwraca false gdy brak danych

Dostęp do pól

Dostęp poprzez indeks lub nazwę
Funkcje Get… - najlepsza

wydajność


Zamknięcie DataReader
Zamkniecie połączenia

while (myReader.Read())
{
str += myReader[1];
str += myReader["field"];
str += myReader.

Get

DateTime(2);

}

// Open Connection and create command
SqlConnection

conn

= new

SqlConnection("data source=localhost;
initial catalog=pubs; integrated
security=true");

SqlCommand cmdAuthors = new
SqlCommand("select * from Authors",

conn

);

conn.Open();

// Create DataReader and read data
SqlDataReader

dr

;

dr = cmdAuthors.

ExecuteReader

();

while (dr.

Read

())

{
lstBuiltNames.Items.Add(dr["au_lname"] + ",
" + dr["au_fname"]);
}

// Close DataReader and Connection
dr.

Close

();

conn.Close();

background image

Transakcje

• Transakcje lokalne

– Dostęp z jednego połączenia
– Udostępnione przez ADO.NET

• Transakcje rozproszone

– Wykonywane na wielu połączniacj
– Użycie Microsoft Distributed Transaction Component

(MSDTC)

– namespace System.Transaction

background image

Transkacje lokalne

ADO.NET wspiera tranzakcyjność

Transakcję rozpoczynamy poprzez metodę

BeginTransaction

która zwraca obiekt

transakcji.

Transakcja wspiera metody wykonujące

zmiany na bazie danych

– polecenia

(Command)

Transakcja jest

Zatwierdzana poprzez

Commit

Wycofywana poprzez

Rollback

<<interface>>
IDbCommand

<<interface>>

IDbTransaction

<<interface>>

IDbConnection

//----- Properties
IDbConnection Connection {

get

;}

IsolationLevel IsolationLevel {

get

;}

// Methods

void

Commit();

void

Rollback();

...

Transaction 1

...
IDbTransaction Transaction {

get

;

set

;}

...

Connection 1

IDbTransaction BeginTransaction();

IDbTransaction BeginTransaction

(IsolationLevel lvl);

background image

Transakcje - przykład

2.

Stworzenie obiektów

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. Definicja

trans

.Commit();

catch

(Exception e) {

if

(trans != null)

trans

.Rollback();

}

finally

{

try

{

con.Close();

}

}

3.

Zatwierdzenie lub cofnięcie wyników

background image

Poziomy izolacji

Definiują blokady na odczyt i zapis

ADO.NET

zapewnia różne poziomy izolacji

ReadUncommitted

Dostęp do zablokowanych danych
Dirty reads

ReadCommitted

Odczyt zablokowanych wierszy zabroniony
Brak dirty read, może wystąpić phantom row
Non-repeatable reads

RepeatableRead

ReadCommitted bez non-repeatable reads

Serializable

Dostęp w seriach
Najwyższy poziom izolacji
Nie występują phantom rows

public enum

IsolationLevel {

ReadUncommitted, ReadCommitted, RepeatableRead, Serializable, ...

}

background image

2.3.3 Tryb bezpołączeniowy: use DataSet

Database

4.

Zwraca

DataSet

do klienta

5.

Zmiana danych przez użytkownika

2.

Tworzenie obiektów SqlConnection i SqlDataAdapter

3.

Wypełnienie

DataSet

z DataAdapter i

zamknięcie połączenia

SqlDataAdapter

SqlConnection

List-Bound

Control

1.

Klient tworzy żądanie wyświetlenia strony

1

2

3

4

5

6.

Aktualizacja danych

DataSet

7.

Użycie SqlDataAdapter do otwarcia
połączenia SqlConnection, aktualizacja
danych w bazie i zamknięcie połączenia

6

7

Client

Web server

DataSet

background image

Czym jest DataSet?

DataSet zawiera wiele

DataTables

Relacje są reprezentowane

poprzez DataRelation

Można wymusić Constrainst
Dostęp do danych w tabelach

poprzez DataRow i
DataColumn

DataTable

DataColumn

DataRow

DataRelation

Tables

DataTable

Relations

DataRelation

DataRelation

DataRow(s)

DataColumn

Constraint(s)

DataTable

DataTable

DataViewManager

DataView

DataSet

– baza danych utrzymywana w pamięci(struktuwa relacyjna)

background image

Stosowanie obiektu DataSet

• gdy dane muszą byd edytowane lub gdy do bazy trzeba dodawad

i usuwad rekordy.

• gdy zachodzi potrzeba organizowania danych - filtrowania, sortowania

czy wyszukiwania

• gdy rekordy pobrane z bazy danych będą przetwarzane w wielu

iteracjach

• gdy wynikowy zbiór danych pomiędzy kolejnymi odwołaniami do tej

samej strony musi zostad zachowany w obiekcie Session lub Cache.

• do przekazywania wyników działania obiektów warstwy biznesowej

i usług Web Service

– odłączony obiekt DataSet może byd serializowany do postaci XML i przesyłany z

wykorzystaniem protokołu HTTP

background image

DataSet vs. DataReader

DataSet

DataReader

Operacje odczytu i zapisu

Tylko do odczytu

Wiele tabel z różnych źródeł

Oparty o jedno polecenie SQL

Bezpołączeniowy

Połączeniowy

Źródło dla wielu kontrolek

Źródło dla jednej kontrolki

Przesuwanie się w przód i tył

Przesuwanie tylko do przodu

Wolniejszy dostęp

Szybszy dostęp

Wspierany przez narzędzia automatyzujące pracę

Wymaga ręcznej implementacji

background image

Diagram klasy DataSet

DataRow

//----- Properties

string

DataSetName {

get

;

set

;

}

DataRelationsCollection Relations {

get

;}

DataTableCollection Tables {

get

;}

PropertyCollection ExtendedProperties {

get

;}

string

NameSpace {

get

;}

bool

HasErrors {

get

;}

...

*

Rows

DataSet

Transaction 1

//----- Properties

string

DataSetName {

get

;

set

;}

DataRelationsCollection Relations {

get

;}

DataTableCollection Tables {

get

;}

PropertyCollection ExtendedProperties {

get

;}

string

NameSpace {

get

;}

bool

HasErrors {

get

;}

...

DataTable

//----- Properties

string

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

DataRelation

//----- Properties

string

RelationName {

get

;

set

;}

DataTable ParentTable {

get

;}

DataColumn[] ParentColumns {

get

;}

DataTable ChildTable {

get

;}

DataColumn[] ChildColumns {

get

;}

...

Relations

*

ParentRelations

*

ChildRelations

*

*
ParentColumns

*
ChildColumns

DataColumn

//----- Properties

bool

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

*

background image

Klasa DataSet

Dostęp do:

DataTable

– DataSet.Tables[0]
– DataSet.Tables*“tablename”+

DataColumn

– DataTable.Columns[0]
– DataTable.Columns*“columnname”+

DataRow

– DataTable.Rows[0]

Pola tabeli

– DataRow[0]
– DataRow*“columnname”+

DataSet

składa się z

Kolecji DataTable
Kolekcji DataRelation

DataTable

składa się z

collection of DataTableColumns

(= schema definition)

collection of DataTableRows

(= data)

DefaultView (DataTableView)

DataRelation

Łączy dwa obiekty DataTable
definiujue ParentTable i

ParentColumns
oraz ChildTable i ChildColumns

background image

Typowany i nietypowany DataSet

Typowany dataset

jest datasetem, który dziedziczony jest z bazowej klasy DataSet, a

następnie na podstawie informacji z bazy danych generuje nową klasę. Informacje o typach
(tabele, kolumny, relacje, …) są dołączane do obiektu.

– VS daje możliwośd automatyczniej generacji typowanych datasetów
– Może zostad zbudowany w oparciu o dane z pliku XSD
– Mniej podatne na błędy
– Mniejsza elastycznośd

Nietypowany dataset

nie posiada wbudowanego schematu. Zawiera również tabele, wiersze,

kolumny, jednak są one udostępniane jako zwykłe kolekcje

– Rozwiązanie bardziej elastyczne, umożliwia pracę z nieznannym źródłem

Porównanie:

– Poprawne dla obu typów:
MyDataSet.Tables[“News”].Rows[0][“Title”]
– Poprawne tylko dla typowanego DataSet + zwraca dane we właściwym formacie
MyDataSet.News[0].Title

background image

Zdarzenia w DataTable

• Podział na trzy kategorie:

• Dla kolumn: ColumnChanging, ColumnChanged

– DataColumnChangeEventsArgs: Column, ProposedValue, Row

• Dla wierszy: RowChanging, RowChanged, RowDeleting,

RowDeleted

– DataRowChangeEventArgs: Action (Add, Change,

ChangeCurrentAndOriginal, ChangeOriginal, Commit, Delete,
Nothing, Rollback), Row

• Dla tabel: TableClearing, TableCleared, TableNewRow

– DataTableClearEventArgs: Table, TableName, TableNamespace
– DataTableNewRowEventArgs key member: Row

background image

Wypełnianie DataSet: DataAdapter

DataAdapter

s

łuży jako most pomiędzy DataSetem a źródłem danych pozwalający

na wymianę danych. DataAdapter reprezentuje zestaw poleceń oraz połączenie
bazodanowe które są uzywane do wypełnia DataSet oraz aktualizacji bazy. Dane są
wymieniane poprzez zapytania SQL lub procedury składowane.

DataAdapter - właściwości:

SelectCommand – odczytuje dane ze źródła
InsertCommand – zapisuje dane z DataSet do bazy
UpdateCommand – aktualizuje dane w bazie danymi z DataSet
DeleteCommand – usuwa dane z DataSer

DataAdapter – metody:

Fill

– odświeża DataSet danymi z bazy (używa SELECT)

Update

– przenosi zmiany z DataSet do bazy (używa INSERT, UPDATE, DELETE)

background image

DataAdapter - polecenia

• Tworzone w trzy sposoby

– Użycie obiektu

CommandBuilder

by stworzyd Command

podczas wykonania

• Proste do realizacji, narzut na wykonanie
• Ograniczenie do Select dla jednej tabeli

– Poprzez

Visual Studio

w trakcie tworzenia aplikacji

• Proste do realizacji, brak narzutu na wykonanie
• Ograniczenie do Select dla jednej tabeli

– Stworzenie programowo podczas tworzenia aplikacji

• Wysoka kontrola i wydajnośd
• Brak ograniczeo
• Narzut na czas implementacji

background image

CommandBuilder

DataTable dt= ds.Tables["movies"];

// Use command builder to generate update commands

SqlCommandBuilder

sb

= new

SqlCommandBuilde

r(

da

);

// Add movie to table

DataRow drow = dt.NewRow();
drow["movie_Title"] = "Taxi Driver";
drow["movie_Year"] = "1976";
dt.Rows.Add(drow);

// Delete row from table

dt.Rows[4].Delete();

// Edit Column value

dt.Rows[5]["movie_Year"] = "1944";

// Update underlying Sql Server table

int updates =

da

.Update(ds, "movies");

MessageBox.Show("Rows Changed: " +updates.ToString());


Obiekt CommandBuilder

generuje polecenia wymagane do aktualizacji źródła

danych po wprowadzeniu zmian w obiekcie DataSet.
Ograniczenia:

polecenie Select dotyczy pojedynczej tabeli
tabela w bazie musi mieć klucz główny lub unikatową kolumnę zawartą w oryginalnym

poleceniu Select

background image

Data Adapter - tworzenie

Zapisanie zapytania w

DataAdapter



Konstruktor ustawia wartość

SelectCommand

Gdy wymagane, utworzenie

InsertCommand

,

UpdateCommand

,

DeleteCommand

SqlDataAdapter da = new SqlDataAdapter

("select * from Authors",

conn

);

da.SelectCommand.CommandText;
da.SelectCommand.Connection;

background image

DataSet - tworzenie

private

void

Demo()

{
SqlDataAdapter

da

=

new

SqlDataAdapter(

"SELECT City FROM Authors",
"Server=localhost; Database=Pubs; Integrated Security=SSPI" );
DataSet ds =

new

DataSet();

da

.

Fill

( ds, "Authors" );

// Opens and closes a connection

foreach

( DataRow dr

in

ds.Tables[ "Authors" ].Rows )

Console.WriteLine( dr[ "City" ] );

// Writes list of cities

}

Ładowanie danych poprzez SelectCommand obiektu DataAdapter

Definicja SQL, przez który zostaną załadowane dane
SelectCommand jako konstruktor

background image

DataSet - tworzenie

Tworzenie i załadowanie danymi DataTable

Fill

wywołuje

SelectCommand

obiektu

DataAdapter









Dostęp do DataTable

DataSet ds = new DataSet();
da.

Fill

(ds, "Authors");

ds.Tables["Authors"].Rows.Count;

string str="";

foreach(DataRow r in
ds.Tables["Authors"].Rows)
{
str += r[2];
str += r["au_lname"];
}

background image

Wypełnianie DataSet

Wydajność

Zdefiniowanie schematu przed wypełnieniem DataSet

DataTables, DataColumns, DataRelations są znane przed załadowaniem danych
Zwiększenie wydajności

Tworzenie typowanych DataSet

:

- dsCustomers.Customers.BeginLoadData();
- daCustomers.Fill(dsCustomers.Customers);
- dsCustomers.Customers.EndLoadData();
- dataGrid1.DataSource = dsCustomers.Customers.DefaultView;;

Dane z wielu DataAdapter

DataSet może przechowywać dane z wielu obiektów DataAdapter

1 DataAdapter = 1 DataTable

Wywołanie metody Fill

Określenie tabeli

- daCustomers.Fill(dsCustomerOrders.Customers);
- daOrders.Fill(dsCustomerOrders.Orders);
- dataGrid1.DataSource = dsCustomerOrders.Customers.DefaultView;

background image

DataSet - podsumowanie

DataSet może:

– Przechowywad dane w wielu powiązanych tabelach
– Modelowad zależności między tabelami
– Zarządza constrainami
– Daje dostęp do widoków celem bardziej efektywnego

wyświetlania danych

– Byd przesyłany pomiędzy procesami i warstwami

DataSet i XML:

– XML może zostad załadowany do DataSet
– DataSet może zostad przesłany jako XML
– DataSet może wczytywad xsd

background image

DataView

DataView służy modyfikowaniu DataTable celem wyświetlenia potrzebych

danych

DefaultView zwraca standardowy widok dla DataTable

Modyfikacja widoku z DataSet poprzez filtry

DataView dv = new DataView(ds.Tables["Authors"]);
dv.

RowFilter

= "state = 'CA'";

DataView dv = ds.Tables["Authors"].DefaultView;

Trzy parametry opcjonalne

Filter,

"City='London'"

Sort

, "CompanyName ASC"

DataViewRowState

background image

Relacje

Kolumna rodzica

Kolumna dziecka

Stworzenie relacji

dr = New DataRelation _
(„CustOrders", parentCol, _
childCol)
ds.DataRelations.Add(dr)

DataColumn parentCol = ds.Tables["Customers

"

].Columns["CustomerID

"

]

childCol = ds.Tables["Orders

"

].Columns["CustomerID

"

]

Orders table

Customers table

DataSet

parentCol

childCol

DataRelation

DataRelation

definiuje relację na potrzeby nawigacji

background image

Nawigacja poprzez relacje

Customers

Orders

GetChildRows

GetParentRow

DataSet

ds.Tables[index].Rows[index].

GetChildRows

("relation");

ds.Tables[index].Rows[index].

GetParentRow

("relation");

DataView tableView;
DataRowView currentRowView;

tableView = new DataView(ds.Tables["Customers"]);

currentRowView

= tableView[dgCustomers.SelectedIndex];

dgChild.DataSource =

currentRowView

.CreateChildView("CustOrders");

Customers

Orders

CreateChildView

DataRowView

DataView

DataSet

background image

Modyfikacja danych w DataTable

BeginEdit rozpoczyna edycję danych
EndEdit i CancelEdit kończą edycję danych

Wstawianie wiersza

Stworzenie wiersza

DataRow

drNewEmployee

= dtEmployees.

NewRow

()

Wypełnienie danymi

drNewEmployee

("EmployeeID") = 11

drNewEmployee

("LastName") = "Smith"

Dodanie do DataTable

dtEmployees.Rows.

Add

(

drNewEmployee

)

Jednowierszowo

dtEmployees.Rows.

Add

( New Object() {11, "Smith"})

DataRos drEmployee =
dtEmployees.Rows(3)
drEmployee.

BeginEdit()

drEmployee("FirstName") = "John"
drEmployee("LastName") = "Smith"
drEmployee.

EndEdit()

background image

Modyfikacja danych w DataTable

Usuwanie wiersza

Metoda

Remove

Usuwa wiersz z kolekcji
Przykład:

dtEmployees.Rows.

Remove

(drEmployee)

Metoda

Delete

klasy DataRow

Oznacza wiersz jako usunięty
Wiersz staje się „ukryty”, możemy uzyskać do niego dostęp
Przykład:

drEmployee.

Delete()

background image

Śledzenie zmian w DataSet

• DataRow może przechowywad wiele wersji wiersza:

– DataRowVersion.

Current

• Aktualna wartośd

– DataRowVersion.

Original

• Wartośd przed dokonaniem zmian

– DataRowVersion.

Proposed

• Wartośd w trakcie cyklu BeginEdit / EndEdit

– DataRowVersion.

Default

• Wartośd standardowa

background image

RowVersion - stany

CURRENT

ORIGINAL

PROPOSED

White

White

N/A

White

White

Brown

Brown

White

N/A

dataRow.BeginEdit();
dataRow[ "au_lname" ]
= "Brown";





dataRow.EndEdit();






dataRow[ "au_lname", DataRowVersion.Current ] // Brown

dataRow[ "au_lname", DataRowVersion.Original ] // White

background image

Diagram stanów obiektu DataRow

DataRow

może być w różnych stanach

public

DataRowState RowState {get;}

public enum

DataRowState {

Added, Deleted, Detached, Modified, Unchanged

}

Detached

Deleted

Unchanged

Modified

row =table.NewRow

table.Row.

Add(row)

Reject-
Changes

row.

Delete

Accept-

Changes

row.Delete

RejectChanges

row.Delete

Accept-

Changes

Accept-

Changes

Reject-

Changes

row[..] = ..

table.Rows.

Remove(row)

Added

background image

Modyfikacja źródła danych

• Modyfikacja źródła danych przez DataAdapter

InsertCommand, UpdateCommand, DeleteCommand

RowState = Modified

RowState = Unchanged

RowState = Added

RowState = Modified

RowState = Deleted

Use UPDATE command

Ignore

Use INSERT command

Use UPDATE command

Use DELETE command

DataRows in DataTable

Modyfikacje są zapisywane poprzez metodę Update obiektu DataAdapter

DataAdapter przeszukuje wiersze pod kątem RowState
Wykonuje akcję zgodnie ze stanem wiersza

background image

Optymalizacja zmian

• DataSet oraz DataTable wspierają metodę

GetChanges

GetChanges bez argumentów

• Pobiera wiersze, których RowState jest inny niż Unchanged
• Wykorzystanie podczas przekazywania między warstwami
dsChanges = ds.

GetChanges

();

GetChanges z argumentem RowState

• Wiersze, które mają określony RowState
• Pozwala zarządzad kolejnością aktualizacji
changes = ds.

GetChanges

( DataRowState.Added );

• Medota Merge pozwala na scalenie danych

background image

Obsługa współbieżnego dostępu do danych

Tryb bezpołączeniowy używa podejścia optymistycznego (optimistic

concurrency)

Zwalnianie blokad podczas rozłączania

Możliwość konfliktów

Dane mogły zostać zmienione

-

Usunięcie wiersza

-

Zmiana wartości w polu wiersza

Wykrywanie konfliktów

Data Adapter Configuration Wizard pozwala generować zapytania SQL

wykrywające konflikty

Podczas aktualizacji:

Porównanie bieżących wartości z oryginalnymi

(where …)

Różnice powodują konflikt

Dodanie do tabeli pola timestamp - aktualizacja pola przy zmianie wartości.

http://msdn.microsoft.com/en-us/library/aa0416cz.aspx

http://msdn.microsoft.com/msdnmag/issues/04/09/DataPoints

background image

Naruszenie spójności danych

Column name

Original value

Current value

Value in database

CustID

101

101

101

LastName

Smith

Smith

Smith

FirstName

Bob

Bob

Bob

Column name

Original value

Current value

Value in database

CustID

101

101

101

LastName

Smith

Smith

Smith

FirstName

Bob

Robert

Bob

Column name

Original value

Current value

Value in database

CustID

101

101

101

LastName

Smith

Smith

Smith

FirstName

Bob

James

Robert

User1 czyta wiersz

User2 zmienia FirstName z "Bob" na "Robert" i zapisuje zmiany

User1 zmienia FirstName na

"James”i próbuje aktualizować bazę

background image

Wykrywanie konfliktów

// Visual C#: How the Data Adapter Configuration Wizard Supports Optimistic Concurrency

this.cmUpdate.CommandText =

"UPDATE Customers " +

"SET CustomerID=@CustomerID, CompanyName=@CompanyName " +

" WHERE (CustomerID =

@Original_CustomerID

) " +

" AND (CompanyName =

@Original_CompanyName

); " +

"SELECT CustomerID, CompanyName FROM Customers " +

" WHERE (CustomerID =

@CustomerID

)";

this.cmUpdate.Parameters.Add(new SqlParameter(

"@CustomerID

", SqlDbType.NChar, 5, ParameterDirection.Input, false, 0, 0, "CustomerID",

DataRowVersion.

Current

, null));

this.cmUpdate.Parameters.Add(new SqlParameter(

"@CompanyName

", SqlDbType.NVarChar, 40,

ParameterDirection.Input, false, 0, 0, "CompanyName", DataRowVersion.

Current

, null));

this.cmUpdate.Parameters.Add(new SqlParameter(

"@Original_CustomerID

", SqlDbType.NChar, 5,

ParameterDirection.Input, false, 0, 0 , "CustomerID", DataRowVersion.

Original

, null));

this.cmUpdate.Parameters.Add(new SqlParameter(

"@Original_CompanyName

",

SqlDbType.NVarChar, 40, ParameterDirection.Input, false, 0, 0, "CompanyName",

DataRowVersion.

Original

, null));

this.cmUpdate.Parameters.Add(new SqlParameter(

"@CustomerID

",

SqlDbType.NChar, 5, ParameterDirection.Input, false, 0, 0, "CustomerID", DataRowVersion.

Current

,

null));

background image

Rozwiązywanie konfliktów

Właściwość

HasErrors

Sprawdza DataSet, DataTable, DataRow

Jedna ze strategii:

“Last in wins” – zmiany są zapisywane niezależnie od stanu
Zatrzymanie wartości w DataSet i aktualizacja później
Odrzut konfliktów i wypełnienie ich danymi z DataSet
Odrzut konfliktów i wypełnienie ich danymi z bazy

background image

Kontrolki źródła danych

ObjectDataSource

Umożliwia połączenie z obiektami logiki biznesowej i innych klas i służy do tworzenia aplikacji
webowych które bazują na obiektach warstwy pośredniej do zarządzania danymi. Wspiera
zaawansowane sortowania i dzielenie na strony niedostępne w innych kontrolkach źródeł
danych.

SqlDataSource

Umożliwia połączenie do serwerów baz danych takich jak Microsoft SQL Server czy Oracle.
We współpracy z serwerem SQL Server wspiera zaawansowane możliwości buforowania.
Kontrolka wspiera również sortowanie, filtrowanie i dzielenie na strony, jeśli dane są zwracane
jako obiekt DataSet.

AccessDataSource

Umożliwia współpracę z bazami danych zapisanymi w Microsoft Access. Kontrolka wspiera
sortowanie, filtrowanie i dzielenie na strony, jeśli dane są zwracane jako obiekt DataSet

XmlDataSource

Umożliwia pobieranie danych zapisanych w plikach XML, szczególnie dla hierarchicznych
kontrolek serwerowych ASP.NET takich jak TreeView. Wspiera filtrowanie przy użyciu wyrażeo
XPath i umożliwia stosowanie transformacji danych przy użyciu XSLT. Umożliwia również
aktualizację danych przez zapisanie całego dokumentu XML ze zmianami.

SiteMapDataSource Używana w ASP.NET do nawigacji na stronie

LinqDataSource

Umożliwia użycie języka LINQ na stronach ASP.NET poprzez model deklaratywny do pobrania
i modyfikowania danych z obiektów danych takich jak tabele w bazie czy kolekcje w pamięci
serwera. Wspiera automatyczne generowanie poleceń wybierania, aktualizacji, dodawania i
usuwania danych. Kontrolka wspiera sortowanie, filtrowanie i dzielenie na strony

EntityDataSource

Umożliwia połączenie z danymi pochodzącymi z modelu Entity Data Model (EDM). Wspiera
automatyczne generowanie poleceń wybierania, aktualizacji, dodawania i usuwania danych.
Kontrolka wspiera sortowanie, filtrowanie i dzielenie na strony.

background image

Połączenie i tworzenie zapytao przy pomocy SqlDataSource

Określić atrybuty kontrolki SqlDataSource:

ConnectionString – łańcuch połączenia.
ProviderName – nazwa dostawcy danych.
SelectCommand – polecenie SQL zawierające treść zapytania do bazy danych lub

nazwa procedury składowanej do wykonania

.

<asp:SqlDataSource

ID="SqlDataSource1" runat="server"

ConnectionString

="Data Source=.\SQLEXPRESS; AttachDbFilename=|DataDirectory|\CDDB.mdf;

Integrated Security=True; User Instance=True"
ProviderName="System.Data.SqlClient"
SelectCommand="SELECT * FROM [Kategorie]">

</asp:SqlDataSource>

<asp:SqlDataSource ID="SqlDataSource1" runat="server"

ConnectionString

="<%$ ConnectionStrings:

PolaczenieDoBazy

%>"

SelectCommand="SELECT * FROM [Kategorie]">
</asp:SqlDataSource>

<connectionStrings>
<add name="

PolaczenieDoBazy

" connectionString="Data Source=.\SQLEXPRESS;

AttachDbFilename=|DataDirectory|\CDDB.mdf;Integrated Security=True; User Instance=True"
providerName="System.Data.SqlClient" />
</connectionStrings>

W bloku <configuration> pliku Web.config

lub

background image

Połączenie i tworzenie zapytao przy pomocy SqlDataSource

• Konfiguracja treści zapytania do bazy

<asp:SqlDataSource

ID="SqlDataSource1" runat="server"

ConnectionString="<%$ ConnectionStrings:PolaczenieDoBazy %>"
SelectCommand="SELECT * FROM [Kategorie]"
DeleteCommand="DELETE FROM [Kategorie] WHERE [KatID] = @KatID"
InsertCommand="INSERT INTO [Kategorie] ([Nazwa]) VALUES (@Nazwa)"
UpdateCommand="UPDATE [Kategorie] SET [Nazwa] = @Nazwa WHERE [KatID] = @KatID">
<DeleteParameters>
<asp:Parameter Name="KatID" Type="Int32" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="Nazwa" Type="String" />
<asp:Parameter Name="KatID" Type="Int32" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="Nazwa" Type="String" />
</InsertParameters>

</asp:SqlDataSource>

background image

XML i Dataset

XML File

DataSet

Object

XmlDataDocument

Object

XslTransform

Object

XML or
HTML File

Database

DataAdapter

ReadXML

Doc.Save

WriteXML

XSLT File

XML File

XML File

background image

Dlaczego używad XML z Dataset

XML to uniwersalny format wymiany danych między klientami
Synchronizacja i transformacja danych

Human Readable

Mainframe Readable

XML File

Or Stream

Browser Readable

Web Server

DataSet

Firewall

Silna integracja

serializacjaDataSet do XML
XML jako źródło danych dla DataSet
Schema dla DataSets zdefiniowana jako XML

schemas

Typowane DataSet generowane z XML schema
Dostęp do DataSet poprzez interfejs XML-DOM

Integracja w systemach rozproszon

background image

Metody klasy DataSet do obsługi danych i schematów XML

• ReadXML

– Ładowanie XML

• WriteXml

- zapis DataSet do strumienia XML

• WriteXmlSchema

– wygenerowanie schemy z DataSet

• ReadXmlSchema –

załadowanie XML Schema

• InferXmlSchema

– stworzenie schemy DataSet na podstawie

XML

• GetXm

l i

GetXmlSchema

– zwraca ciąg XML lub XML Schema

background image

Metody klasy DataSet do obsługi danych i

schematów XML

Use ReadXml to load data from a file or stream

Use WriteXml to write XML data to a file or stream

Use GetXml to write data to a string variable

DataSet ds = new DataSet();

ds.

ReadXml

(Server.MapPath("filename.xml"));

DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter("select * from

Authors", conn);

da.Fill(ds);
ds.

WriteXml

(Server.MapPath("filename.xml"));

string strXmlDS = ds.

GetXml

();

background image

Synchronizacja DataSet z XmlDataDocument

Załadowanie XML Data do XmlDataDocument

XmlDataDocument objXmlDataDoc = new XmlDataDocument();
objXmlDataDoc.

Load

(Server.MapPath ("file.xml"));

DataSet

ds

= new DataSet();

//fill in ds
objXmlDataDoc = new XmlDataDocument(

ds

);

Załadowanie DataSet do XmlDataDocument

background image

Praca z XmlDataDocument

Załadowanie danych



Pobranie wierszy jako XML



Metody XML DOM

– XmlDataDocument dziedziczy z XmlDocument

XmlElement elem;
elem = objXmlDataDoc.GetElementFromRow(ds.Tables[0].Rows[1]);

dg.DataSource = objXmlDataDoc.DataSet;


Wyszukiwarka

Podobne podstrony:
ADO NET 2005
Obiekty ADO NET
Slide Lập Trình Trên Môi Trường Windows Với ADO NET Phạm Minh Tuấn, 23 Trang
ADO NET 2005
Developing A Universal Data Access Layer Leveraging Ado Net, C Sharp And Factory Design Pattern
Technologie ASP NET i ADO NET w Visual Web Developer techas
ASP NET Module 3 Using Microsoft ADO NE
Safety net
ESUR net
adolf hitler mein kampf (osloskop net) ZYE3G5GRRLG3LZFEKTQK5ONTMSA4RS4AODH356A
fantastyka 1983 02 (osloskop net) EYSUMLI3CQZEUUUE3G4HMELKUEEJV5F7XZ5UQHQ
17 rzs 2012 13 net wersja pods Nieznany (2)

więcej podobnych podstron