Uložení dat zpět do databáze v aplikacích .NET Framework

Poznámka:

Datové sady a související třídy jsou staršími technologiemi rozhraní .NET Framework z počátku 2000, které aplikacím umožňují pracovat s daty v paměti, zatímco aplikace jsou odpojené od databáze. Jsou zvláště užitečné pro aplikace, které uživatelům umožňují upravovat data a uchovávat změny zpět do databáze. I když se datové sady ukázaly jako velmi úspěšná technologie, doporučujeme, aby nové aplikace .NET používaly Entity Framework Core. Entity Framework poskytuje přirozenější způsob práce s tabulkovými daty jako objektovými modely a má jednodušší programovací rozhraní.

Datová sada je kopie dat v paměti. Pokud tato data upravíte, je vhodné tyto změny uložit zpět do databáze. Uděláte to jedním ze tří způsobů:

  • Voláním jedné z Update metod TableAdapter

  • Voláním jedné z DBDirect metod TableAdapter

  • UpdateAll Voláním metody v Objektu TableAdapterManager, který sada Visual Studio vygeneruje za vás, když datová sada obsahuje tabulky, které souvisejí s jinými tabulkami v datové sadě

Při vytváření vazby tabulek datových sad k ovládacím prvkům na stránce Windows Form nebo XAML funguje architektura datových vazeb za vás.

Pokud znáte TableAdaptery, můžete přejít přímo na jedno z těchto témat:

Téma Popis
Vkládání nových záznamů do databáze Provádění aktualizací a vkládání pomocí objektů TableAdapter nebo Command
Aktualizace dat pomocí objektu TableAdapter Postup provádění aktualizací pomocí objektů TableAdapter
Hierarchická aktualizace Jak provádět aktualizace z datové sady se dvěma nebo více souvisejícími tabulkami
Zpracování výjimky souběžnosti Zpracování výjimek při pokusu dvou uživatelů o změnu stejných dat v databázi najednou
Postupy: Ukládání dat pomocí transakce Jak uložit data v transakci pomocí systému. Obor názvů transakcí a objekt TransactionScope
Uložení dat do transakce Návod, který vytvoří model Windows Forms aplikaci, která demonstruje ukládání dat do databáze uvnitř transakce
Uložení dat do databáze (více tabulek) Úprava záznamů a uložení změn v několika tabulkách zpět do databáze
Uložení dat z objektu do databáze Jak předat data z objektu, který není v datové sadě do databáze pomocí metody TableAdapter DbDirect
Ukládání dat pomocí metod TableAdapter DBDirect Jak používat TableAdapter k odesílání dotazů SQL přímo do databáze
Uložení datové sady ve formátu XML Jak uložit datovou sadu do dokumentu XML

Dvoufázové aktualizace

Aktualizace zdroje dat je dvoustupňový proces. Prvním krokem je aktualizace datové sady novými záznamy, změněnými záznamy nebo odstraněnými záznamy. Pokud vaše aplikace tyto změny nikdy neodesílá zpět do zdroje dat, budete s aktualizací hotovi.

Pokud změny odešlete zpět do databáze, je potřeba provést druhý krok. Pokud nepoužíváte ovládací prvky vázané na data, musíte ručně volat Update metodu stejného objektu TableAdapter (nebo datového adaptéru), který jste použili k naplnění datové sady. Můžete ale také použít různé adaptéry, například k přesunu dat z jednoho zdroje dat do jiného nebo k aktualizaci více zdrojů dat. Pokud nepoužíváte datovou vazbu a ukládáte změny pro související tabulky, musíte ručně vytvořit instanci proměnné automaticky generované TableAdapterManager třídy a pak volat její UpdateAll metodu.

Koncepční diagram aktualizací datové sady

Datová sada obsahuje kolekce tabulek, které obsahují kolekce řádků. Pokud chcete později aktualizovat podkladový zdroj dat, musíte při přidávání nebo odebírání řádků použít metody ve DataTable.DataRowCollection vlastnosti. Tyto metody provádějí sledování změn, které je potřeba k aktualizaci zdroje dat. Pokud voláte kolekci u RemoveAt vlastnosti Řádky, odstranění se nepředá zpět do databáze.

Sloučení datových sad

Obsah datové sady můžete aktualizovat jejich sloučením s jinou datovou sadou. To zahrnuje zkopírování obsahu zdrojové datové sady do volající datové sady (označované jako cílová datová sada). Při sloučení datových sad se do cílové datové sady přidají nové záznamy ve zdrojové datové sadě. Kromě toho se do cílové datové sady přidají další sloupce ve zdrojové datové sadě. Sloučení datových sad je užitečné, když máte místní datovou sadu a získáte druhou datovou sadu z jiné aplikace. Je také užitečné, když získáte druhou datovou sadu ze komponenty, jako je webová služba XML, nebo když potřebujete integrovat data z více datových sad.

Při slučování datových sad můžete předat logický argument (preserveChanges), který metodě říká Merge , jestli se mají zachovat stávající úpravy v cílové datové sadě. Vzhledem k tomu, že datové sady udržují více verzí záznamů, je důležité mít na paměti, že se slučuje více než jedna verze záznamů. Následující tabulka ukazuje, jak se sloučí záznam ve dvou datových sadách:

Datarowversion Cílová datová sada Zdrojová datová sada
Původní James Wilson James C. Wilson
Aktuální Jim Wilson James C. Wilson

Merge Volání metody v předchozí tabulce s preserveChanges=false targetDataset.Merge(sourceDataset) výsledky v následujících datech:

Datarowversion Cílová datová sada Zdrojová datová sada
Původní James C. Wilson James C. Wilson
Aktuální James C. Wilson James C. Wilson

Merge Volání metody s preserveChanges = true targetDataset.Merge(sourceDataset, true) výsledky v následujících datech:

Datarowversion Cílová datová sada Zdrojová datová sada
Původní James C. Wilson James C. Wilson
Aktuální Jim Wilson James C. Wilson

Upozornění

preserveChanges = trueRejectChanges Pokud je metoda volána u záznamu v cílové datové sadě, vrátí se k původním datům ze zdrojové datové sady. To znamená, že pokud se pokusíte aktualizovat původní zdroj dat cílovou datovou sadou, nemusí být schopen najít původní řádek, který se má aktualizovat. Porušení souběžnosti můžete zabránit vyplněním jiné datové sady aktualizovanými záznamy ze zdroje dat a následným sloučením, aby se zabránilo porušení souběžnosti. (Porušení souběžnosti nastane, když jiný uživatel po vyplnění datové sady upraví záznam ve zdroji dat.)

Omezení aktualizací

Pokud chcete provést změny existujícího datového řádku, přidejte nebo aktualizujte data v jednotlivých sloupcích. Pokud datová sada obsahuje omezení (například cizí klíče nebo omezení s možnou hodnotou null), je možné, že záznam může být při aktualizaci dočasně v chybovém stavu. To znamená, že po dokončení aktualizace jednoho sloupce může být v chybovém stavu, ale než se dostanete k dalšímu sloupci.

Chcete-li zabránit předčasně porušení omezení, můžete dočasně pozastavit omezení aktualizace. Slouží k dvěma účelům:

  • Zabrání vyvolání chyby po dokončení aktualizace jednoho sloupce, ale nezačal aktualizovat jiný sloupec.

  • Zabrání vyvolání určitých událostí aktualizace (události, které se často používají k ověření).

Poznámka:

V model Windows Forms architektura datových vazeb, která je integrovaná do datagridu, pozastaví kontrolu omezení, dokud se fokus nepřesune mimo řádek a není nutné explicitně volat BeginEdit, EndEditnebo CancelEdit metody.

Omezení jsou při Merge vyvolání metody v datové sadě automaticky zakázána. Po dokončení sloučení dojde k nějakému omezení datové sady, která nelze povolit, ConstraintException vyvolá se. V této situaci EnforceConstraints je vlastnost nastavena a false, všechna porušení omezení musí být vyřešena před resetováním EnforceConstraints vlastnosti na true.

Po dokončení aktualizace můžete znovu spustit kontrolu omezení, která také znovu umožňuje aktualizovat události a vyvolat je.

Další informace o pozastavení událostí najdete v tématu Vypnutí omezení při vyplňování datové sady.

Chyby aktualizace datové sady

Když aktualizujete záznam v datové sadě, je možné, že dojde k chybě. Můžete například neúmyslně zapsat data nesprávného typu do sloupce nebo dat, která jsou příliš dlouhá, nebo data, která mají nějaký jiný problém s integritou. Nebo můžete mít kontroly ověřování specifické pro aplikaci, které můžou vyvolat vlastní chyby během jakékoli fáze události aktualizace. Další informace najdete v tématu Ověření dat v datových sadách.

Údržba informací o změnách

Informace o změnách v datové sadě se uchovávají dvěma způsoby: označením řádků, které označují, že se změnily (RowState) a udržováním více kopií záznamu (DataRowVersion). Pomocí těchto informací můžou procesy určit, co se změnilo v datové sadě, a můžou odesílat příslušné aktualizace do zdroje dat.

Vlastnost RowState

Vlastnost RowState objektu DataRow je hodnota, která poskytuje informace o stavu konkrétního řádku dat.

Následující tabulka podrobně popisuje možné hodnoty výčtu DataRowState :

Hodnota DataRowState Popis
Added Řádek byl přidán jako položka do objektu DataRowCollection. (Řádek v tomto stavu nemá odpovídající původní verzi, protože neexistuje, když byla volána poslední AcceptChanges metoda).
Deleted Řádek byl odstraněn pomocí Delete objektu DataRow .
Detached Řádek byl vytvořen, ale není součástí žádné DataRowCollection. Objekt DataRow je v tomto stavu ihned po jeho vytvoření, před jeho přidáním do kolekce a po odebrání z kolekce.
Modified Hodnota sloupce v řádku se nějakým způsobem změnila.
Unchanged Řádek se od AcceptChanges posledního zavolání nezměnil.

Výčet DataRowVersion

Datové sady udržují více verzí záznamů. Pole DataRowVersion se používají při načítání hodnoty nalezené DataRow v objektu Item[] pomocí vlastnosti nebo GetChildRows metody objektu DataRow .

Následující tabulka podrobně popisuje možné hodnoty výčtu DataRowVersion :

Hodnota DataRowVersion Popis
Current Aktuální verze záznamu obsahuje všechny úpravy provedené u záznamu od posledního AcceptChanges zavolání. Pokud byl řádek odstraněn, neexistuje žádná aktuální verze.
Default Výchozí hodnota záznamu definovaná schématem datové sady nebo zdrojem dat.
Original Původní verze záznamu je kopie záznamu, protože byla naposledy potvrzena změny v datové sadě. V praxi je to obvykle verze záznamu, která se čte ze zdroje dat.
Proposed Navrhovaná verze záznamu, která je k dispozici dočasně, když jste uprostřed aktualizace – to znamená mezi dobou, kterou jste volali metodu BeginEdit a metodu EndEdit . Obvykle získáte přístup k navrhované verzi záznamu v obslužné rutině pro událost, například RowChanging. Vyvolání CancelEdit metody obrátí změny a odstraní navrženou verzi řádku dat.

Původní a aktuální verze jsou užitečné při přenosu informací o aktualizaci do zdroje dat. Při odeslání aktualizace do zdroje dat se obvykle nové informace pro databázi nachází v aktuální verzi záznamu. Informace z původní verze slouží k vyhledání záznamu, který se má aktualizovat.

Například v případě, že se změní primární klíč záznamu, potřebujete způsob, jak vyhledat správný záznam ve zdroji dat, aby bylo možné změny aktualizovat. Pokud neexistuje žádná původní verze, záznam by se pravděpodobně připojil ke zdroji dat, což by vedlo nejen k nadbytečné nežádoucímu záznamu, ale i v jednom záznamu, který je nepřesný a zastaralý. Tyto dvě verze se také používají v řízení souběžnosti. Můžete porovnat původní verzi se záznamem ve zdroji dat a určit, jestli se záznam od načtení do datové sady změnil.

Navrhovaná verze je užitečná, když potřebujete provést ověření, než skutečně potvrdíte změny datové sady.

I když se záznamy změnily, nejsou vždy původní ani aktuální verze tohoto řádku. Když do tabulky vložíte nový řádek, neexistuje žádná původní verze, pouze aktuální verze. Podobně pokud odstraníte řádek voláním metody tabulky Delete , existuje původní verze, ale žádná aktuální verze.

Pomocí dotazu na metodu datového řádku můžete otestovat, jestli existuje konkrétní verze záznamu HasVersion . K libovolné verzi záznamu můžete získat přístup předáním DataRowVersion hodnoty výčtu jako volitelného argumentu, když požadujete hodnotu sloupce.

Získání změněné záznamy

Běžným postupem není aktualizovat každý záznam v datové sadě. Uživatel může například pracovat s ovládacím prvku model Windows FormsDataGridView, který zobrazuje mnoho záznamů. Uživatel ale může aktualizovat jenom několik záznamů, odstranit jeden a vložit nový. Datové sady a tabulky dat poskytují metodu (GetChanges) pro vrácení pouze upravených řádků.

Pomocí metody tabulky dat (GetChanges) nebo samotné datové sady (GetChanges) můžete vytvořit podmnožinu změněných záznamůGetChanges. Pokud zavoláte metodu pro tabulku dat, vrátí kopii tabulky pouze se změněnými záznamy. Podobně pokud voláte metodu pro datovou sadu, získáte novou datovou sadu s pouze změněnými záznamy.

GetChanges sama o sobě vrátí všechny změněné záznamy. Naproti tomu předáním požadovaného DataRowState parametru GetChanges metodě můžete určit, jakou podmnožinu změněných záznamů chcete: nově přidané záznamy, záznamy označené k odstranění, odpojení záznamů nebo upravených záznamů.

Získání podmnožině změněných záznamů je užitečné, když chcete odeslat záznamy do jiné komponenty ke zpracování. Místo odesílání celé datové sady můžete snížit režii při komunikaci s jinou komponentou tím, že získáte jenom záznamy, které komponenta potřebuje.

Potvrzení změn v datové sadě

Při změnách v datové sadě RowState se nastaví vlastnost změněných řádků. Původní a aktuální verze záznamů jsou vytvořeny, udržovány a zpřístupněny vámi RowVersion vlastností. Metadata uložená ve vlastnostech těchto změněných řádků jsou nezbytná pro odesílání správných aktualizací do zdroje dat.

Pokud změny odrážejí aktuální stav zdroje dat, tyto informace už nemusíte udržovat. Datová sada a její zdroj se obvykle synchronizují dvěma způsoby:

  • Okamžitě po načtení informací do datové sady, například při čtení dat ze zdroje.

  • Po odeslání změn z datové sady do zdroje dat (ale ne dříve), protože byste ztratili informace o změnách, které jsou potřeba k odeslání změn do databáze).

Čekající změny můžete potvrdit do datové sady voláním AcceptChanges metody. Obvykle se AcceptChanges volá v následujících časech:

  • Po načtení datové sady. Pokud načtete datovou sadu voláním metody TableAdapter Fill , adaptér za vás automaticky potvrdí změny. Pokud ale načtete datovou sadu sloučením jiné datové sady, musíte změny potvrdit ručně.

    Poznámka:

    Adaptéru můžete zabránit automatickému potvrzení změn při volání Fill metody nastavením AcceptChangesDuringFill vlastnosti adaptéru na false. Pokud je nastavená na falsehodnotu , nastaví RowState se každý řádek vložený během výplně na Addedhodnotu .

  • Po odeslání změn datové sady do jiného procesu, například webové služby XML.

    Upozornění

    Potvrzení změny tímto způsobem vymaže všechny informace o změnách. Neprovázejte změny, dokud nedokončíte provádění operací, které vyžadují, aby vaše aplikace věděla, jaké změny byly provedeny v datové sadě.

Tato metoda provádí následující:

Metoda AcceptChanges je k dispozici na třech úrovních. Můžete ho volat u objektu DataRow , který potvrdí změny pouze pro tento řádek. Můžete ho také volat u objektu DataTable , který potvrdí všechny řádky v tabulce. Nakonec ho DataSet můžete na objektu volat a potvrdit všechny čekající změny ve všech záznamech všech tabulek datové sady.

Následující tabulka popisuje, které změny jsou potvrzeny na základě objektu, na kterém je metoda volána:

metoda Výsledek
System.Data.DataRow.AcceptChanges Změny jsou potvrzeny pouze na konkrétním řádku.
System.Data.DataTable.AcceptChanges Změny jsou potvrzeny na všech řádcích v konkrétní tabulce.
System.Data.DataSet.AcceptChanges Změny se potvrdí na všech řádcích ve všech tabulkách datové sady.

Poznámka:

Pokud načtete datovou sadu voláním metody TableAdapter Fill , nemusíte explicitně přijímat změny. Metoda ve výchozím nastavení Fill volá metodu AcceptChanges po dokončení naplnění tabulky dat.

Související metoda , RejectChangesvrátí zpět účinek změn zkopírováním Original verze zpět do Current verze záznamů. Nastaví také RowState každý záznam zpět na Unchanged.

Ověření dat

Abyste ověřili, že data ve vaší aplikaci splňují požadavky procesů, kterým se předávají, často musíte přidat ověření. To může zahrnovat kontrolu správnosti zadání uživatele ve formuláři, ověřování dat odesílaných do vaší aplikace jinou aplikací nebo dokonce kontrola, jestli informace počítané v rámci vaší komponenty spadají do omezení vašeho zdroje dat a požadavků na aplikaci.

Data můžete ověřit několika způsoby:

  • V obchodní vrstvě přidáním kódu do aplikace ověřte data. Datová sada je jedním místem, kde to můžete udělat. Datová sada poskytuje některé výhody back-endového ověřování – například možnost ověřit změny, když se mění hodnoty sloupců a řádků. Další informace najdete v tématu Ověření dat v datových sadách.

  • V prezentační vrstvě přidáním ověřování do formulářů. Další informace najdete v tématu Ověření vstupu uživatele v model Windows Forms.

  • V back-endu dat odešlete data do zdroje dat , například do databáze, a umožníte jim přijmout nebo odmítnout data. Pokud pracujete s databází, která má sofistikovaná zařízení pro ověřování dat a poskytování informací o chybách, může to být praktický přístup, protože data můžete ověřit bez ohledu na to, odkud pocházejí. Tento přístup ale nemusí vyhovět požadavkům na ověření specifické pro aplikaci. Kromě toho může mít ověření zdroje dat za následek celou řadu cest ke zdroji dat v závislosti na tom, jak vaše aplikace usnadňuje řešení chyb ověření vyvolaných back-endem.

    Důležité

    Při použití datových příkazů s CommandType vlastností, která je nastavena na Text, pečlivě zkontrolujte informace odeslané z klienta před předáním do databáze. Uživatelé se zlými úmysly se mohou pokusit odeslat (vložit) upravené nebo další příkazy SQL ve snaze získat neoprávněný přístup nebo poškodit databázi. Před přenosem uživatelského vstupu do databáze vždy ověřte, zda jsou informace platné. Osvědčeným postupem je vždy používat parametrizované dotazy nebo uložené procedury, pokud je to možné.

Přenos aktualizací do zdroje dat

Po provedení změn v datové sadě můžete změny přenést do zdroje dat. Nejčastěji to uděláte voláním Update metody TableAdapter (nebo datového adaptéru). Metoda prochází každý záznam v tabulce dat, určuje požadovaný typ aktualizace (aktualizace, vložení nebo odstranění), pokud existuje, a potom spustí příslušný příkaz.

Představte si, jak se aktualizace provádějí, předpokládejme, že vaše aplikace používá datovou sadu, která obsahuje jednu tabulku dat. Aplikace načte dva řádky z databáze. Po načtení vypadá tabulka dat v paměti takto:

(RowState)     CustomerID   Name             Status
(Unchanged)    c200         Robert Lyon      Good
(Unchanged)    c400         Nancy Buchanan    Pending

Vaše aplikace změní stav Nancy Buchanan na "Preferovaný". V důsledku této změny se hodnota RowState vlastnosti pro tento řádek změní z Unchanged na Modified. Hodnota RowState vlastnosti prvního řádku zůstává Unchanged. Tabulka dat teď vypadá takto:

(RowState)     CustomerID   Name             Status
(Unchanged)    c200         Robert Lyon      Good
(Modified)     c400         Nancy Buchanan    Preferred

Vaše aplikace teď volá metodu Update pro přenos datové sady do databáze. Metoda kontroluje jednotlivé řádky zase. Pro první řádek metoda nepřenáší do databáze žádný příkaz SQL, protože tento řádek se od původního načtení z databáze nezměnil.

Pro druhý řádek však Update metoda automaticky vyvolá správný datový příkaz a přenese ho do databáze. Konkrétní syntaxe příkazu SQL závisí na dialektu SQL, který je podporovaný podkladovým úložištěm dat. Ale následující obecné vlastnosti přenášeného příkazu SQL jsou důležité:

  • Přenášený příkaz SQL je příkaz UPDATE . Adaptér ví, že používá UPDATE příkaz, protože hodnota RowState vlastnosti je Modified.

  • Přenášený příkaz SQL obsahuje WHERE klauzuli označující, že cílem UPDATE příkazu je řádek, kde CustomerID = 'c400'. Tato část SELECT příkazu rozlišuje cílový řádek od všech ostatních, protože CustomerID je primárním klíčem cílové tabulky. Informace pro WHERE klauzuli jsou odvozeny z původní verze záznamu (DataRowVersion.Original), pokud se změnily hodnoty potřebné k identifikaci řádku.

  • Přenášený příkaz SQL obsahuje SET klauzuli, která nastaví nové hodnoty upravených sloupců.

    Poznámka:

    Pokud vlastnost TableAdapter UpdateCommand byla nastavena na název uložené procedury, adaptér nekonstruuje příkaz SQL. Místo toho vyvolá uloženou proceduru s příslušnými parametry předanými.

Parametry předání

Parametry obvykle slouží k předání hodnot pro záznamy, které se budou aktualizovat v databázi. Když metoda TableAdapter Update spustí UPDATE příkaz, musí vyplnit hodnoty parametrů. Získá tyto hodnoty z Parameters kolekce pro příslušný datový příkaz – v tomto případě UpdateCommand objekt v TableAdapter.

Pokud jste k vygenerování datového adaptéru použili nástroje sady Visual Studio, UpdateCommand obsahuje objekt kolekci parametrů, které odpovídají jednotlivým zástupným symbolům parametrů v příkazu.

System.Data.SqlClient.SqlParameter.SourceColumn Vlastnost každého parametru odkazuje na sloupec v tabulce dat. SourceColumn Například vlastnost pro parametry au_id a Original_au_id parametry je nastavena na jakýkoli sloupec v tabulce dat obsahuje ID autora. Když se metoda adaptéru Update spustí, přečte sloupec ID autora ze záznamu, který se aktualizuje, a vyplní hodnoty do příkazu.

UPDATE V příkazu musíte zadat jak nové hodnoty (ty, které budou zapsány do záznamu), tak i staré hodnoty (aby záznam mohl být umístěn v databázi). Existují tedy dva parametry pro každou hodnotu: jeden pro SET klauzuli a jiný pro klauzuli WHERE . Oba parametry čtou data ze záznamu, který se aktualizuje, ale na základě vlastnosti parametru SourceVersion získají různé verze hodnoty sloupce. Parametr klauzule SET získá aktuální verzi a parametr klauzule WHERE získá původní verzi.

Poznámka:

Hodnoty v kolekci Parameters můžete také nastavit sami v kódu, což byste obvykle udělali v obslužné rutině události pro událost datového adaptéru RowChanging .