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...
Určitě si přečtěte

Nebuďte jako Emma Watson. Poradíme, jak nepřijít o hanbaté fotky

Nebuďte jako Emma Watson. Poradíme, jak nepřijít o hanbaté fotky

** Pokud už choulostivé snímky vyfotíte, dbejte na jejich zabezpečení ** Útočníci je nejčastěji získají z cloudového úložiště ** Pozor si dejte i na phishing a řádné zabezpečení telefonu

25.  3.  2017 | Stanislav Janů | 55

Aktualizační nástroj Microsoftu nabízí přechod na Creators Update. Funguje to! [Aktualizováno: už ne]

Aktualizační nástroj Microsoftu nabízí přechod na Creators Update. Funguje to! [Aktualizováno: už ne]

** Aktualizace Creators Update pro Windows 10 ještě nebyla oficiálně uvolněna ** Už ale existuje způsob, jak jí ze serverů Microsoftu dostat ** Úspěšně jsme to vyzkoušeli

28.  3.  2017 | Jakub Čížek | 68

Facebook chce odříznout Google od hlavního zdroje příjmů

Facebook chce odříznout Google od hlavního zdroje příjmů

** Facebook otevřel vlastní reklamní síť dalším hráčům ** Snaží se prosadit efektivnější spojení mezi vydavatelem a inzerentem ** Weby mohou dosáhnout zvýšení příjmů z reklamy až o 30 %

27.  3.  2017 | Karel Javůrek | 12


Aktuální číslo časopisu Computer

První test AMD Ryzen

Velké testy: 22 powerbank a 8 bezdrátových setů

Radíme s koupí Wi-Fi routeru

Inteligentní domy