reklama

Poznáváme C# a Microsoft .NET 62. díl – DataTable II.

V minulém díle jsme se začali podrobněji zabývat třídou DataTable a jelikož se jedná o objekt velmi důležitý, pokračovat v jeho popisu budu i dnes a to mimo jiné představením možnosti zjistit stavy jednotlivých řádků vysvětlením úlohy těchto stavů.

Akceptování změn a stavy řádků

Kromě základních vlastností objektu DataRow, které byly probrány v rámci minulého dílu stojí za zmínku ještě jedna vlastnost, která určuje stav datového řádku vzhledem k tabulce do které patří nebo by měl patřit. Jak již víme, tak za vytvoření nové instance třídy DataRow, představující záznam v tabulce, je zodpovědná tabulka samotná a to metodou NewRow.

Tím, že je vytvořen datový řádek, nutně neznamená, že již patří do nějaké tabulky, protože nově vytvořený řádek ještě musí být přidán do kolekce řádku tabulky. To, že do žádné tabulky řádek nepatří, nebo že je v tabulce daný řádek nový, nebo byl řádek z tabulky odstraněn je zjistitelné pomocí vlastnosti RowState. Přečtením hodnoty této vlastnosti tedy zjistíme, které řádky byly přidány, změněny nebo odebrány případně jestli řádek do nějaké tabulky vůbec patří.

/// <summary>
/// Ukazka zmeny stavu objektu DataRow
/// </summary>
public class RowStateInfo
{
  public static void PrintStateInfo()
  {
    DataTable table = MakeTable();
    DataRow newRow = table.NewRow();
    //detached
    Console.WriteLine("Stav radku : {0}", newRow.RowState);
    table.Rows.Add(newRow);
    //added
    Console.WriteLine("Stav radku : {0}", newRow.RowState);
    //potrvdit vsechny zmeny provedne s radky v tabulce
    table.AcceptChanges();
    //unchanged
    Console.WriteLine("Stav radku : {0}", newRow.RowState);
    newRow["FirstName"] = "Petr";
    //modified
    Console.WriteLine("Stav radku : {0}", newRow.RowState);
    //deleted
    newRow.Delete();
    Console.WriteLine("Stav radku : {0}", newRow.RowState);
    //pocet je 1
    Console.WriteLine("Pocet radku v tabulce : {0}", table.Rows.Count);
    table.AcceptChanges();
    //pocet je 0
    Console.WriteLine("Pocet radku v tabulce : {0}", table.Rows.Count);
    }

  //vytvori objekt DataTable
  static DataTable MakeTable()
  {
    DataTable table = new DataTable("Employees");
    DataColumn idCol = table.Columns.Add("ID", typeof(Int32));
    idCol.AllowDBNull = false;
    idCol.Unique = true;
    idCol.AutoIncrement = true;
    table.Columns.Add("FirstName", typeof(String));
    table.Columns.Add("SurName", typeof(String));
    return table;
  }
}

Po vytvoření řádky pomocí metody NewRow objektu DataTable, je řádek ve stavu Detached, což značí, že není součástí žádné kolekce řádků (DataRowCollection). Po přidání do kolekce tabulky se jeho stav změní na Added, značící, že řádek byl do kolekce přidán a čeká na potvrzení změn tabulky. Potvrzení změn tabulky se děje zavoláním metody AcceptChanges na objektu DataTable.

Po zavolání této metody se stav řádku změní na Unchanged, tj. že s ním nebyly provedeny žádné změny od posledního zavolání metody AcceptChanges nebo od doby, kdy byl vytvořen datovým adaptérem (objektem implementující rozhraní IDataAdapter) a jeho metodou Fill (známe s úvodního příkladu na odpojené aplikace).

Když je řádek změněn zapsáním nějaké hodnoty do jedné z jeho složek (sloupců) je do potvrzení změn ve stavu Modified. Zavoláním metody Delete na objektu datového řádku zapříčiníme jeho odstranění, což je reflektováno změnou jeho stavu na Deleted a po akceptování změn tabulky se již v tabulce nabude nalézat. Do té doby však stále figuruje v kolekci Rows dané tabulky jak je ukázáno v příkladu.

Stavy jednotlivých řádků a akceptace změn tabulky jsou velmi důležitou vlastností těchto datových objektů, protože těchto vlastností je interně využíváno při synchronizaci DataSetu (do něhož jednotlivé objekty DataTable náleží) s datovým zdrojem, což ,jak již víme, se děje pomocí datového adaptéru.

Datový adaptér totiž ve chvíli, kdy promítá změny v jednotlivých datových tabulkách v objektu DataSet do konkrétního datového zdroje, kontroluje stavy jednotlivých objektů DataRow a v závislosti na těchto stavech vykonává nad datovým zdrojem potřebné příkazy pro přidání, změnu či odebrání reálných záznamů.

Odmítnutí změn

V předchozím příkladu bylo ukázáno, jak spolu souvisí stavy jednotlivých datových řádků a metoda AcceptChanges objektu DataTable, která akceptuje provedené změny. Tak jako je možné všechny provedené změny od posledního potvrzení změn či vytvoření objektu DataTable datovým adaptérem potvrdit, tak je samozřejmě možné tyto provedené změny i odmítnout. To znamená, že všechny přidané řádky při odmítnutí změn v tabulce nebudou a naopak všechny řádky, které byly odstraněny metodou Delete, budou v tabulce nadále. K odmítnutí změn slouží metoda RejectChanges objektu DataTable a její použití můžete vidět v následujícím příkladu.

/// <summary>
/// Ukazka odmitnuti zmen objektu DataTable
/// </summary>
public class RejectingChangesExample
{
  public static void Run()
  {
    DataTable table = MakeTable();
    //vytvoreni noveho radku
    DataRow newRow = table.NewRow();
    newRow["FirstName"] = "Petr";
    //pridani noveho radku do tabulky
    table.Rows.Add(newRow);
    //bude 1
    Console.WriteLine("Pocet radku v tabulce : {0}", table.Rows.Count);
    //odmitnuti zmen
    table.RejectChanges();
    //bude 0
    Console.WriteLine("Pocet radku v tabulce : {0}", table.Rows.Count);
    //znovu pridame radek do tabulky
    table.Rows.Add(newRow);
    //potvrdime zmeny
    table.AcceptChanges();
    //odstranime pridany radek
    table.Rows[0].Delete();
    table.RejectChanges();
    //bude 1
    Console.WriteLine("Pocet radku v tabulce : {0}", table.Rows.Count);
  }
   
static DataTable MakeTable()
  {
    //vytvoreni je stejne jako v prikladu RowStateInfo
  }
}

Kalkulované hodnoty ve sloupcích

Stejně jako ve světě relačních databázových systémů je možné hodnoty v některých sloupcích tabulky kalkulovat a to ať už podle nějakého vzorce nebo nějakou agregační funkcí typu součet či průměr. K vytvoření sloupce, jehož hodnota bude kalkulována, využijeme instanční vlastnosti Expression typu DataColumn.

/// <summary>
/// Ukazka pouziti vlastnosti Expression tridy DataColumn
/// </summary>
public class ExpressionExample
{
  public static void Run()
  {
    DataTable items = MakeTable();
    FillTable(items);
    PrintTable(items);
  }
   
  //vytvori objekt DataTable
  static DataTable MakeTable()
  {
    DataTable table = new DataTable("Products");
    DataColumn nameCol = table.Columns.Add("Name", typeof(string));
    DataColumn priceCol = table.Columns.Add("Price", typeof(int));
    DataColumn priceWithTaxCol = table.Columns.Add("PriceWithTax", typeof(int));
    //nastaveni vyrazu pro vypocet hodnoty sloupce
    priceWithTaxCol.Expression = "Price * 1.19";
    return table;
  }

  //naplni objekt DataTable daty
  static void FillTable(DataTable table)
  {
    DataRow record1 = table.NewRow();
    DataRow record2 = table.NewRow();
    record1["Name"] = "Vyrobek 1";
    record1["Price"] = 2000;
    record2["Name"] = "Vyrobek 2";
    record2["Price"] = 3000;
    table.Rows.Add(record1);
    table.Rows.Add(record2);
  }

  //vypise obsah objektu DataTable
  static void PrintTable(DataTable table)
  {
    foreach(DataRow lRow in table.Rows)
    {
      foreach(DataColumn lCol in table.Columns)
      {
        Console.Write("{0} - {1}, ", lCol.ColumnName, lRow[lCol]);
      }
      Console.WriteLine();
    }
  }
}

V příkladu je vytvořena tabulka na evidenci informací o produktech a sloupec PriceWithTax představující cenu s daní obsahuje ve své vlastnosti Expression výraz, kterým bude počítána jeho hodnota pro jednotlivé řádky v tabulce. Jak bylo naznačeno výše, tak jako výraz může být, kromě v příkladu použitého vzorce, i agregační funkce typu Sum, Avg a několik dalších.

Příklady ke článku je možné stáhnout zde.

Témata článku: Software, Microsoft, Programování, Public

1 komentář

Nejnovější komentáře

  • Pavel Polívka 24. 11. 2007 13:53:04
    Programovou oflline verzi seriálu naleznete ke stažení na...
reklama
Určitě si přečtěte

UPC překopli páteřní kabel. V Brně i druhý den nejede internet ani kabelovka

UPC překopli páteřní kabel. V Brně i druhý den nejede internet ani kabelovka

** V Brně byl velký výpadek služeb UPC ** Důvodem je překopnutý páteřní kabel ** V některých lokalitách služby stále nefungují

5.  12.  2016 | Jakub Čížek | 103

17 expertek Microsoftu předpovědělo rok 2027. Splní se alespoň něco?

17 expertek Microsoftu předpovědělo rok 2027. Splní se alespoň něco?

** Zmizí klasické vyhledávače ** Budeme programovat buňky ** Kvantové počítače překonají šifry

6.  12.  2016 | Jakub Čížek | 36

11 tipů na dobrý stolní počítač: od základu po herní mašiny

11 tipů na dobrý stolní počítač: od základu po herní mašiny

** Postavte si stolní počítač! Máme pro vás 11 vzorových sestav s rozpisem komponent ** Většina tipů cílí na hráče, věnujeme se ale i základnímu PC a počítačům na střih videa ** Nadělte si nový počítač třeba pod stromeček

5.  12.  2016 | Adam Kahánek | 74

Nejlepší notebooky nad 20 tisíc: poradíme, které teď chcete

Nejlepší notebooky nad 20 tisíc: poradíme, které teď chcete

** V notebooku s cenou nad 20 tisíc nesmí chybět kvalitní displej a rychlé úložiště ** Za dalších deset tisíc můžete dostat navíc styl nebo výkonnější komponenty ** Vybírat můžete z různých velikostí i konstrukcí

8.  12.  2016 | Stanislav Janů | 85


reklama