Sunteți pe pagina 1din 16

Disconnecte Clases

(DataTable, DataView si DataSet)

Accesul la date este factorul crucial in toate aplicatiile, iar ADO.NET ofera mijloace
de accesare a datelor in aplicatii. ADO.NET este o arhitectura de date deconectata. Datele
sunt extrase din baza de date si stocate pe calculatorul local. Datele se manipuleaza pe
computerul local, iar conectarea la baza de date se realizeaza doar cand se doreste modificarea
inregistrrilor sau extragerea de noi date. Aceste clase se regasesc in dll-ul System.Data.

Clasa DataTable:
Un obiect de tip DataTable reprezinta date stocate in memorie sub forma de linii si coloane
care pot avea sau nu constrangeri. Un obiect de tip DataTable se populeaza cu alte obiecte de
tip DataColumn si DataRow care contin datele propriu-zise.

Obiectele DataTable nu sunt utile pana cand nu le cream o schema adaugand obiecte
DataColumn si setand constrangeri pe fiecare coloana pentru a mentine integritatea datelor si
a limita cantitatea de date pe care o putem adauga.
Incepem prin a crea un tabel simplu si cateva coloane:

DataTable Cellphones = new DataTable("cell");


DataColumn IMEI = new DataColumn("IMEI"); // numele coloanei intre paranteze
IMEI.DataType = typeof(string); // (default string) precizeaza tipul de date din coloana
int/string/etc
IMEI.MaxLength = 15; // (default -1 -fara limita-) lungimea maxima a textului admisa (ex:
nvarchar(30) )
IMEI.Unique = true; // (default false) permite duplicarea intrarilor pe aceasta coloana (daca
fiecare item din coloana e unic, coloana este primary key pentru tabel)
IMEI.AllowDBNull = false; // (default true) specifica daca pe coloana pot exista valori nule
IMEI.Caption = "IMEICaption"; // (default "numele coloanei") sir cu care notam partea
dintr`un grafic care reprezinta coloana
Cellphones.Columns.Add(IMEI); // Met Columns returneaza coloanele

Daca nu avem nicio coloana care sa contina elemente unice ( Unique = false ), putem adauga
o coloana index care sa se incrementeze automat pe masura ce adaugam noi linii in tabel.
Acest lucru se face setand proprietatea AutoIncrement a unei coloane true,
AutoIncrementSeed la valoarea de la care vrem sa se inceapa indexarea si AutoIncrementStep
la valoare cu care sa se incrementeze de fiecare data cand un nou rand este adaugat. Cand se
face trimiterea de date dintr-o baza de date locala unei alte baze de date back-end, coloana
care contine indexurile nu se trimite si noile randuri sunt indexate in continuarea celor
existente, insa la o interogare in care este necesara extragerea de informatii din ambele baze
de date, indexurile comune vor genera o exceptie. Pentru a evita acest lucru, indexarea din
baza de date locala trebuie sa fie negativa, AutoIncrementSeed si AutoIncrementStep sa fie
negative deoarece baza de date principala nu va genera numere negative.

IMEI.AutoIncrement = true;
IMEI.AutoIncrementSeed = 1;
IMEI.AutoIncrementStep = 1;

Un obiect DataRow poate fi creat numai in contextul unui DataTable deoarece trebuie sa se
conformeze constrangerilor de pe fiecare coloana. Metoda Rows dintr-un obiect DataTable
returneaza randurile care din tabel, iar metoda Add adauga un nou rand.
DataRow tel1 = Cellphones.NewRow(); //DataRow se conformeaza regulilor din cell
tel1["IMEI"] = "12345";
tel1["Producator"] = "Samsung";
tel1["Proprietar"] = "Andrei";
Cellphones.Rows.Add(tel1);
//metoda 2 de adaugare a unui rand nou
Cellphones.Rows.Add("12876", "Samsung", "Mihai");//Met Rows returneaza randuri

Clasa DataTable are si cateva metode supraincarcate Load care pot fi folosite pentru a adauga
un nou rand tabelului sau sa faca update unuia deja existent. Pentru a folosi metoda Load este
necesar ca tabelul sa aiba setat Primary key. Sunt cateva optiuni pentru LoadOption:
- OverwriteChanges: Rescrie randul deja existent care are acelasi PK cu cel nou si
modifica statutul randurilor la Unchanged;
- PreserveChanges(default): Rescrie randul deja existent dar nu modifica statutul
acestuia;
- Upsert: Rescrie randul deja existent dar nu-i modifica statutul. Randurile noi vor avea
statut de Added, iar cele cu statut Unchanged vor deveni Modified;

Cellphones.PrimaryKey = new DataColumn[] { IMEI }; // setam coloana IMEI ca PK

Cellphones.LoadDataRow(new Object[]
{"12876","Motorola","Mihai"}, LoadOption.OverwriteChanges);

//LoadOption controleaza modul in care datele sursa (noi) sunt scrise, iar
overwriteChanges asigura scrierea
//Load este o metoda supraincarcata care poate fi folosita fie pt update, fie pentru
scriere
//daca se modifica primary key atunci nu se inlocuieste, ci se adauga (este necesara
prezenta unei coloane Primary Key in tabel )

Accept changes este folosit pentru lucru cu baza de date principala si atunci cand apelam
metoda, sincronizam baza noastra de date locala cu cea principala.

Afisarea informatiilor din tabel o putem face printr-o functie de parsare-afisare:

foreach (DataRow dataRow in Cellphones.Rows)


{
foreach (var item in dataRow.ItemArray)
{
Console.Write("{0} ", item);
}
Console.WriteLine();
}

sau folosind un obiect de tip StringBuilder si parsare:

public static void EnumerateTable(DataTable DT)


{
var buffer = new StringBuilder();
foreach (DataColumn dc in DT.Columns)
{
buffer.AppendFormat("{0,15} ", dc.ColumnName);
}
buffer.Append("\r\n\n");
Console.WriteLine();
foreach (DataRow dr in DT.Rows)
{
foreach (DataColumn dc in DT.Columns)
{
buffer.AppendFormat("{0,15} ", dr[dc]);
}
buffer.Append("\r\n");
}

string s = buffer.ToString();
Console.WriteLine(s);
}

Starea unui obiect de tip DataRow este importanta, este o proprietate a acestuia si se
gaseste in mai multe stari:
Detached Obiectul a fost creat dar nu a fost adaugat niciunui tabel;
Added obiectul a fost creat si adaugat unui tabel;
Unchanged obiectul nu a fost modificat de la ultimul apel al metodei AcceptChanges;
Modified obiectul a fost modificat de la ultimul apel al metodei sus mentionate.
Deleted obiectul a fost sters din tabel.

Un obiect DataTable poate retine pana la 3 versiuni diferite ale unui singur rand: cea
originala, cea curenta si cea propusa. Atunci cand un rand este incarcat pentru prima data in
tabel, acesta este trecut in versiunea curenta (Current), deoarece versiunea originala implica
adaugarea si modificarea in prealabil a randului. Executand metoda BeginEdit, randul va intra
in modul editare si datele modificate vor fi puse in instanta Proposed urmand ca la chemarea
metodei EndEdit datele curente sa fie trecute in instanta Original, iar cele noi sa le suprascrie
pe cele curente. Daca executam din nou editarea randului, atunci procedura nu va mai afecta
starea originala.

Putem observa schimbarile ce se produc asupra acestor stari, prin codul de mai jos. Functia
GetDataRowInfo verifica starile fiecarui rand si le afiseaza:

private static string GetDataRowInfo(DataRow row, string columnName)


{
string retVal = string.Format(
"RowState: {0} \r\n",
row.RowState);
foreach( string versionString in Enum.GetNames(typeof(DataRowVersion)) )
{
DataRowVersion version = (
DataRowVersion)Enum.Parse(
typeof(DataRowVersion), versionString);
if( row.HasVersion(version) )
{
retVal += string.Format(
"Version: {0} Value: {1} \r\n",
version, row[columnName, version]);
}
else
{
retVal += string.Format(
"Version: {0} does not exist.\r\n",
version);
}
}
return retVal;
}

Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));
Cellphones.AcceptChanges();
Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));

tel1.BeginEdit();
tel1 ["IMEI"] = "54321";
Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));
tel1.EndEdit();
Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));

tel1.BeginEdit();
tel1["IMEI"] = "99999";
Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));
tel1.EndEdit();
Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));

Pentru a copia tabelul integral folosim metoda Copy() din clasa DataTable.

DataTable copie = Cellphones.Copy();


Console.WriteLine("Afisam copia tabelului !!!");
EnumerateTable(copie);
Pentru a copia doar schema tabelului principal, folosim metoda Clone() din Clasa DataTable.

DataTable clone = Cellphones.Clone();


Console.WriteLine("Afisam clona tabelului !!!");
EnumerateTable(clone);

Pentru a copia un rand dintr-un tabel se foloseste metoda ImportRow care copiaza randul
impreuna cu starea originala si cea curenta.

clone.ImportRow(copie.Rows[0]);
EnumerateTable(clone);
clone.AcceptChanges();
clone.Rows[0].BeginEdit();

clone.Rows[0].EndEdit();
Console.WriteLine(GetDataRowInfo(clone.Rows[0], "IMEI"));

namespace Curs
{
class Program
{
static void Main(string[] args)
{
try
{

DataTable Cellphones = new DataTable("cell");


DataColumn IMEI = new DataColumn("IMEI"); // numele coloanei intre paranteze
IMEI.DataType = typeof(string); // (default string) precizeaza tipul de date din
coloana int/string/etc
IMEI.MaxLength = 15; // (default -1 -fara limita-) lungimea maxima a textului admisa
(ex: nvarchar(30) )
IMEI.Unique = true; // (default false) permite duplicarea intrarilor pe aceasta coloana
(daca fiecare item din coloana e unic, coloana este primary key pentru tabel)
IMEI.AllowDBNull = false; // (default true) specifica daca pe coloana pot exista valori
nule
IMEI.Caption = "IMEICaption"; // (default "numele coloanei") sir cu care notam
partea dintr`un grafic care reprezinta coloana
Cellphones.Columns.Add(IMEI); // Met Columns returneaza coloanele
Cellphones.PrimaryKey = new DataColumn[] { IMEI };
DataColumn P = new DataColumn("Producator");
P.AllowDBNull = false;
P.DataType = typeof(string);
P.MaxLength = 20;
P.Unique = false;
P.Caption = "Producator";

Cellphones.Columns.Add(P);

DataColumn pp = new DataColumn("Proprietar");


pp.MaxLength = 20;

Cellphones.Columns.Add(pp);

DataRow tel1 = Cellphones.NewRow(); //DataRow se conformeaza regulilor din cell


tel1["IMEI"] = "12345";
tel1["Producator"] = "Samsung";
tel1["Proprietar"] = "Andrei";
Cellphones.Rows.Add(tel1);
//metoda 2 de adaugare a unui rand nou
Cellphones.Rows.Add("12876", "Samsung", "Mihai");//Met Rows returneaza randuri
Cellphones.LoadDataRow(new Object[] { "12876", "Motorola", "ION" },
LoadOption.OverwriteChanges);

foreach( DataRow dataRow in Cellphones.Rows )


{
foreach( var item in dataRow.ItemArray )
{
Console.Write("{0} ", item);
}
Console.WriteLine();
}

Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));
Cellphones.AcceptChanges();
Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));

tel1.BeginEdit();
tel1["IMEI"] = "54321";
Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));
tel1.EndEdit();
Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));

tel1.BeginEdit();
tel1["IMEI"] = "99999";
Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));
tel1.EndEdit();
Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));

DataTable copie = Cellphones.Copy();


Console.WriteLine("Afisam copia tabelului !!!");
EnumerateTable(copie);

DataTable clone = Cellphones.Clone();


Console.WriteLine("Afisam clona tabelului !!!");
EnumerateTable(clone);

clone.ImportRow(copie.Rows[0]);
EnumerateTable(clone);
clone.AcceptChanges();
clone.Rows[0].BeginEdit();

clone.Rows[0].EndEdit();
Console.WriteLine(GetDataRowInfo(clone.Rows[0], "IMEI"));

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

public static void EnumerateTable(DataTable DT)


{
var buffer = new StringBuilder();
foreach( DataColumn dc in DT.Columns )
{
buffer.AppendFormat("{0,7} ", dc.ColumnName);
}
buffer.Append("\r\n\n");
Console.WriteLine();
foreach( DataRow dr in DT.Rows )
{
foreach( DataColumn dc in DT.Columns )
{
buffer.AppendFormat("{0,15} ", dr[dc]);
}
buffer.Append("\r\n");
}

string s = buffer.ToString();
Console.WriteLine(s);
}

public static void Print(DataTable dt)


{

foreach( DataRow dataRow in dt.Rows )


{
foreach( var item in dataRow.ItemArray )
{
Console.Write("{0,4} ", item);
}
Console.WriteLine();
}

public static string GetDataRowInfo(DataRow row, string columnName)


{
string retVal = string.Format(
"RowState: {0} \r\n",
row.RowState);
foreach( string versionString in Enum.GetNames(typeof(DataRowVersion)) )
{
DataRowVersion version = (
DataRowVersion)Enum.Parse(
typeof(DataRowVersion), versionString);
if( row.HasVersion(version) )
{
retVal += string.Format(
"Version: {0} Value: {1} \r\n", version, row[columnName, version]);
}
else
{
retVal += string.Format("Version: {0} does not exist.\r\n", version);
}
}
return retVal;
}

public static void EnumerateView(DataView view)


{
var buffer = new StringBuilder();
foreach( DataColumn dc in view.Table.Columns )
{
buffer.AppendFormat("{0,15} ", dc.ColumnName);
}
buffer.Append("\r\n");
foreach( DataRowView dr in view )
{
foreach( DataColumn dc in view.Table.Columns )
{
buffer.AppendFormat("{0,15} ", dr.Row[dc]);
}
buffer.Append("\r\n");
}
string s = buffer.ToString();
Console.WriteLine(s);
}
}
}

DataView

Un obiect de tip DataView functioneaza ca o fereastra catre un obiect de tip DataTable


. Un tabel poate avea mai multe obiecte DataView care asigura o vizualizare a datelor din mai
multe perspective fara a fi necesar un nou query catre baza de date.

Sortare:
DataView view = new DataView(Cellphones);
view.Sort = "IMEI DESC"; //sortarea randurilor in functie de IMEI (default ascendenta)
foreach( DataRowView row in view )
{
Console.WriteLine(" {0} \t {1} \t {2}", row["IMEI"], row["Proprietar"], row["Producator"]); //
afisarea sortarii
}

Cautare mai rapida in tabele folosind proprietatile RowFilter si RowStateFilter:


Proprietatea RowFilter este asemanatoare cu clauza WHERE din SQL.
view.RowFilter = "IMEI < 15000 "; // seteaza expresia dupa care randurile vor fi vizualizate
EnumerateView(view); //Important este sa nu avem mai multe filtre active deoarece doar
ultimul va fi aplicat
view.RowFilter = "Producator like 'S%' ";
EnumerateView(view);

Metoda RowStateFilter ofera un filtru care se aplica metodei RowState pe fiecare rand al
tabelului. Acest filtru asigura o metoda usoara de a citi versiuni diferite de randuri de date din
tabel. Folosirea acestei metode implica folosirea valorilor de enumarare din DataViewRwState
care sunt niste flag-uri pe biti asupra carora putem folosi operatorul OR ( | ) pentru a crea
filtre. Flagurile sunt:
- Added : returneaza versiunea curenta a randurilor care au statutul ADDED;
- CurrentRows : similar cu Added;
- Deleted : returneaza versiunea originala a randurilor cu statutul DELETED;
- ModifiedCurrent : returneaza versiunea curenta a randurilor care au statutul
MODIFIED;
- ModifiedOriginal : returneaza versiunea originala a randurilor care au statutul
MODIFIED;
- None : returneaza toate randurile, elimina toate filtrele;
- originalRows : returneaza randurile care au o versiune originala;
- Unchanged : returneaza randurile care au versiunea UNCHANGED;

tel1.BeginEdit();
tel1["IMEI"] = "88888";
Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));
tel1.EndEdit();
Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));
view.RowStateFilter = DataViewRowState.ModifiedCurrent;
EnumerateView(view);

Pentru a exporta o vizualizare a tabelului intr-un tabel propriu-zis, folosim metoda ToTable
din clasa DataView.
DataTable export = view.ToTable("Nume_tabela", true, "Proprietar", "IMEI"); // putem adauga
oricate elemente
EnumerateTable(export);

static void Main(string[] args)


{
try
{
DataTable Cellphones = new DataTable("cell");
DataColumn IMEI = new DataColumn("IMEI"); // numele coloanei intre paranteze
IMEI.DataType = typeof(string); // (default string) precizeaza tipul de date din
coloana int/string/etc
IMEI new DataColumn("Proprietar");
pp.MaxLength = 20;

Cellphones.Columns.Add(pp);

DataRow tel1 = Cellphones.NewRow(); //DataRow se conformeaza regulilor din cell


tel1["IMEI"] = "12345";
tel1["Producator"] = "Samsung";
tel1["Proprietar"] = "Andrei";
Cellphones.Rows.Add(tel1);
//metoda 2 de adaugare a unui rand nou
Cellphones.Rows.Add("12876", "Samsung", "Mihai");//Met Rows returneaza randuri

Cellphones.LoadDataRow(new Object[] { "67800", "Motorola", "ION" },


LoadOption.OverwriteChanges);

DataView view = new DataView(Cellphones);


view.Sort = "IMEI"; //sortarea randurilor in functie de IMEI (default ascendenta)
foreach( DataRowView row in view )
{
Console.WriteLine(" {0} \t {1} \t {2}", row["IMEI"], row["Proprietar"],
row["Producator"]); // afisarea sortarii
}
view.RowFilter = "IMEI < 12500 "; // seteaza expresia dupa care randurile vor fi
vizualizate
EnumerateView(view);
view.RowFilter = "Producator like 'M%' ";
EnumerateView(view);

tel1.BeginEdit();
tel1["IMEI"] = "88888";
Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));
tel1.EndEdit();
Console.WriteLine(GetDataRowInfo(tel1, "IMEI"));
view.RowStateFilter = DataViewRowState.ModifiedCurrent;
EnumerateView(view);
DataTable export = view.ToTable("Nume_tabela", true, "Proprietar", "IMEI"); //
+Proprietar putem adauga oricate elemente
EnumerateTable(export);

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

}public static void EnumerateTable(DataTable DT)


{
var buffer = new StringBuilder();
foreach (DataColumn dc in DT.Columns)
{
buffer.AppendFormat("{0,15} ", dc.ColumnName);
}
buffer.Append("\r\n\n");
Console.WriteLine();
foreach (DataRow dr in DT.Rows)
{
foreach (DataColumn dc in DT.Columns)
{
buffer.AppendFormat("{0,15} ", dr[dc]);
}
buffer.Append("\r\n");
}

string s = buffer.ToString();
Console.WriteLine(s);
}

public static string GetDataRowInfo(DataRow row, string columnName)


{
string retVal = string.Format(
"RowState: {0} \r\n",
row.RowState);
foreach( string versionString in Enum.GetNames(typeof(DataRowVersion)) )
{
DataRowVersion version = (
DataRowVersion)Enum.Parse(
typeof(DataRowVersion), versionString);
if( row.HasVersion(version) )
{
retVal += string.Format(
"Version: {0} Value: {1} \r\n", version, row[columnName, version]);
}
else
{
retVal += string.Format("Version: {0} does not exist.\r\n",version);
}
}
return retVal;
}

public static void EnumerateView(DataView view)


{
var buffer = new StringBuilder();
foreach( DataColumn dc in view.Table.Columns )
{
buffer.AppendFormat("{0,15} ", dc.ColumnName);
}
buffer.Append("\r\n");
foreach( DataRowView dr in view )
{
foreach( DataColumn dc in view.Table.Columns )
{
buffer.AppendFormat("{0,15} ", dr.Row[dc]);
}
buffer.Append("\r\n");
}
string s = buffer.ToString();
Console.WriteLine(s);
}

DataSet

Clasa DataSet lucreaza la nivelul memoriei, este obiectul principal deconectat.Clasa


contine o colectie de obiecte DataTable si DataRelation si ofera metode proprii de clonare si
copiere a tabelelor sau unire. Un obiect DataSet poate contine mai multe tabele si relatiile
dintre ele.

DataSet DateVanzatori = new DataSet("DateVanzatori");


DataTable dt = DateVanzatori.Tables.Add("Vanzatori"); // adaugam tabelul Vanzatori
la obiectul DateVanzatori
dt.Columns.Add("Id", typeof(Guid));
dt.Columns.Add("Nume", typeof(string));
dt.Columns.Add("Addresa2", typeof(string));
dt.Columns.Add("Oras", typeof(string));
dt.Columns.Add("Tara", typeof(string));
dt.PrimaryKey = new DataColumn[] { dt.Columns["Id"] }; // setam PK pentru
Vanzatori

DataTable Piese = DateVanzatori.Tables.Add("Piese"); //adaugam tabelul Piese la


obiectul DateVanzatori
Piese.Columns.Add("Id", typeof(Guid));
Piese.Columns.Add("Id_Vanzator", typeof(Guid));
Piese.Columns.Add("Cost", typeof(decimal));
Piese.PrimaryKey = new DataColumn[] { Piese.Columns["Id"] };// setam PK pentru
Piese

DateVanzatori.Relations.Add("Piese_V", dt.Columns["Id"],
Piese.Columns["Id_Vanzator"]); // am adaugat o relatie de tip Primary Key intre cele doua
tabele

Guid id = Guid.NewGuid(); // cream un Guid


dt.Rows.Add(id, "Ionel", "pipera", "bucuresti", "romania"); // adaugam lui dt un rand
Guid id2 = Guid.NewGuid();
dt.Rows.Add(id2, "Mihai", "1Mai", "Craiova", "romania");
Guid id3 = Guid.NewGuid();
dt.Rows.Add(id3, "Radu", "Brooklyn", "New York", "SUA");
dt.AcceptChanges();
Print(dt); // va aparea si in vanzatori

DataRow piesa = Piese.NewRow();


piesa["Id_Vanzator"] = id;//adaugam id-ul creat mai sus la piesa pt ca sunt in relatie
coloanele
piesa["Id"] = Guid.NewGuid();
piesa["Cost"] = 125;
Piese.Rows.Add(piesa);
Print(dt);
Print(Piese);

Metoda DataRelation pune obiectele de tip DataTable din acelasi obiect DataSet in relatii de
tip PK si join si asigura navigarea usoara intre acestea.
DateVanzatori.Relations.Add("Piese_V", dt.Columns["Id"], Piese.Columns["Id_Vanzator"], true);
// am adaugat o relatie de tip Primary Key intre cele doua tabele

//Navigate parent to children


StringBuilder s = new StringBuilder();
s.Append("\r\nParent to Children\r\n");
DataRow[] childParts = dt.Rows[0].GetChildRows("Piese");
foreach( DataRow dr in childParts )
{
s.Append(string.Format("Piesa: {0} from {1}\r\n", dr["cost"], dt.Rows[0]
["Nume"]));
}
s.Append("--------------------------------\r\n");
//Navigate child to parent
s.Append("\r\nChild to Parent\r\n");
DataRow parentRow = Piese.Rows[0].GetParentRow("Vanzatori");
s.Append(string.Format("Vanzator: {0} for {1}\r\n", Piese.Rows[0]["Cost"]));
s.Append("--------------------------------\r\n");

Mai multe obiecte DataSet pot fi combinate intr-unul singur folosing metoda Merge care
poate lucra pe toate tipurile de obiecte continute in clasa.
//cream un obiect de date master
DataSet masterData = new DataSet("Sales");
DataTable people = masterData.Tables.Add("People");
people.Columns.Add("Id", typeof(Guid));
people.Columns.Add("Name", typeof(string));
people.PrimaryKey = new DataColumn[] { people.Columns["Id"] };
people.Rows.Add(Guid.NewGuid(), "Joe");
Console.WriteLine("DataSet`ul initial");
EnumerateTable(masterData.Tables[0]);

DataSet tempData = masterData.Copy();


Console.WriteLine("DataSet-ul copiat");
EnumerateTable(tempData.Tables[0]);
//introducem datele lui Joe
DataTable tempPeople = tempData.Tables["People"];
DataRow joe = tempPeople.Select("Name='Joe'")[0];
Guid joeId = (Guid)joe["Id"];
//Schimbam numele lui Joe
joe["Name"] = "Joe in Sales";

//cream un tabel cu comenzi si ii adaugam comenzi lui Joe


DataTable orders = tempData.Tables.Add("Orders");
orders.Columns.Add("Id", typeof(Guid));
orders.Columns.Add("PersonId", typeof(Guid));
orders.Columns.Add("Amount", typeof(decimal));
orders.PrimaryKey = new DataColumn[] { orders.Columns["Id"] };
orders.Rows.Add(Guid.NewGuid(), joeId, 100);

masterData.Merge(tempData, false, MissingSchemaAction.AddWithKey);


EnumerateTable(masterData.Tables[0]);
Codul de mai sus creaza un obiect DataSet care contine un sigur tabel numit People si
adaugam o intrare. Statutul randului nou este Added. In continuare, copiem obiectul
masterData intr-un alt obiect numit tempData si ii modificam si numele lui Joe. Cream in
tempData un nou tabel numit Orders si ii adaugam un rand.
Cand apelam metoda Merge, o apelam cu 3 parametrii:
- tempData: numele obiectului de tip DataSet din care se iau datele;
- false: un Boolean care tine locul intructiunii preserveChanges si specifica daca datele
din tempData pot sau nu sa le inlocuiasca pe cele din masterData;
- MissingSchemaAction: este un parametru dintr-o enumeratie. Valorile pe care le
poate lua sunt:
- Add: adauga tabelele si coloanele dintr-un alt obiect pentru a completa o schema;
- AddWithKey: adauga tabelele, coloanele si PK dintr-un alt obiect pentru a completa
schema;
- Error: arunca o exceptie in cazul in care o coloana de date nu exista in obiectul care
este updatat;
- Ignore: ignora datele care se gasesc pe coloanele care sunt in plus in cazul de mai sus;

Cand folosim metoda Merge este impetuos necesar sa avem setat un PK. In cazul in care
niciun PK nu este setat, comanda Merge va functiona ca si o comanda Append.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;

namespace Curs
{
class Program
{
static void Main(string[] args)
{
try
{
DataSet DateVanzatori = new DataSet("DateVanzatori");
DataTable dt = DateVanzatori.Tables.Add("Vanzatori"); // adaugam tabelul Vanzatori
la obiectul DateVanzatori
dt.Columns.Add("Id", typeof(Guid));
dt.Columns.Add("Nume", typeof(string));
dt.Columns.Add("Addresa2", typeof(string));
dt.Columns.Add("Oras", typeof(string));
dt.Columns.Add("Tara", typeof(string));
dt.PrimaryKey = new DataColumn[] { dt.Columns["Id"] }; // setam PK pentru
Vanzatori

DataTable Piese = DateVanzatori.Tables.Add("Piese"); //adaugam tabelul Piese la


obiectul DateVanzatori
Piese.Columns.Add("Id", typeof(Guid));
Piese.Columns.Add("Id_Vanzator", typeof(Guid));
Piese.Columns.Add("Cost", typeof(decimal));
Piese.PrimaryKey = new DataColumn[] { Piese.Columns["Id"] };// setam PK pentru
Piese
DateVanzatori.Relations.Add("Piese_V", dt.Columns["Id"],
Piese.Columns["Id_Vanzator"]); // am adaugat o relatie de tip Primary Key intre cele doua
tabele

Guid id = Guid.NewGuid(); // cream un Guid


dt.Rows.Add(id, "Ionel", "pipera", "bucuresti", "romania"); // adaugam lui dt un rand
Guid id2 = Guid.NewGuid();
dt.Rows.Add(id2, "Mihai", "1Mai", "Craiova", "romania");
Guid id3 = Guid.NewGuid();
dt.Rows.Add(id3, "Radu", "Brooklyn", "New York", "SUA");
dt.AcceptChanges();
Print(dt); // va aparea si in vanzatori

DataRow piesa = Piese.NewRow();


piesa["Id_Vanzator"] = id;//adaugam id-ul creat mai sus la piesa pt ca sunt in relatie
coloanele
piesa["Id"] = Guid.NewGuid();
piesa["Cost"] = 125;
Piese.Rows.Add(piesa);
Print(dt);
Print(Piese);

//cream un obiect de date master


DataSet masterData = new DataSet("Sales");
DataTable people = masterData.Tables.Add("People");
people.Columns.Add("Id", typeof(Guid));
people.Columns.Add("Name", typeof(string));
people.PrimaryKey = new DataColumn[] { people.Columns["Id"] };
people.Rows.Add(Guid.NewGuid(), "Joe");
Console.WriteLine("DataSet`ul initial");
EnumerateTable(masterData.Tables[0]);

DataSet tempData = masterData.Copy();


Console.WriteLine("DataSet-ul copiat");
EnumerateTable(tempData.Tables[0]);
//introducem datele lui Joe
DataTable tempPeople = tempData.Tables["People"];
DataRow joe = tempPeople.Select("Name='Joe'")[0];
Guid joeId = (Guid)joe["Id"];
//Schimbam numele lui Joe
joe["Name"] = "Joe in Sales";

//cream un tabel cu comenzi si ii adaugam comenzi lui Joe


DataTable orders = tempData.Tables.Add("Orders");
orders.Columns.Add("Id", typeof(Guid));
orders.Columns.Add("PersonId", typeof(Guid));
orders.Columns.Add("Amount", typeof(decimal));
orders.PrimaryKey = new DataColumn[] { orders.Columns["Id"] };
orders.Rows.Add(Guid.NewGuid(), joeId, 100);

masterData.Merge(tempData, false, MissingSchemaAction.AddWithKey);


EnumerateTable(masterData.Tables[0]);

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

public static void EnumerateTable(DataTable DT)


{
var buffer = new StringBuilder();
foreach( DataColumn dc in DT.Columns )
{
buffer.AppendFormat("{0,7} ", dc.ColumnName);
}
buffer.Append("\r\n\n");
Console.WriteLine();
foreach( DataRow dr in DT.Rows )
{
foreach( DataColumn dc in DT.Columns )
{
buffer.AppendFormat("{0,15} ", dr[dc]);
}
buffer.Append("\r\n");
}

string s = buffer.ToString();
Console.WriteLine(s);
}

public static void Print(DataTable dt)


{

foreach( DataRow dataRow in dt.Rows )


{
foreach( var item in dataRow.ItemArray )
{
Console.Write("{0,4} ", item);
}
Console.WriteLine();
}
Console.WriteLine();
Console.WriteLine();

public static string GetDataRowInfo(DataRow row, string columnName)


{
string retVal = string.Format(
"RowState: {0} \r\n",
row.RowState);
foreach( string versionString in Enum.GetNames(typeof(DataRowVersion)) )
{
DataRowVersion version = (
DataRowVersion)Enum.Parse(
typeof(DataRowVersion), versionString);
if( row.HasVersion(version) )
{
retVal += string.Format(
"Version: {0} Value: {1} \r\n", version, row[columnName, version]);
}
else
{
retVal += string.Format("Version: {0} does not exist.\r\n", version);
}
}
return retVal;
}
public static void EnumerateView(DataView view)
{
var buffer = new StringBuilder();
foreach( DataColumn dc in view.Table.Columns )
{
buffer.AppendFormat("{0,15} ", dc.ColumnName);
}
buffer.Append("\r\n");
foreach( DataRowView dr in view )
{
foreach( DataColumn dc in view.Table.Columns )
{
buffer.AppendFormat("{0,15} ", dr.Row[dc]);
}
buffer.Append("\r\n");
}
string s = buffer.ToString();
Console.WriteLine(s);
}
}
}

S-ar putea să vă placă și