Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
által Scott Mitchell
Megtudhatja, hogyan frissíthet több adatbázisrekordot egyetlen műveletben. A felhasználói felület rétegben létrehozunk egy GridView-t, ahol minden sor szerkeszthető. Az adatelérési rétegben egy tranzakció több frissítési műveletét is körbefuttatjuk, hogy az összes frissítés sikeres legyen, vagy az összes frissítés vissza legyen állítva.
Bevezetés
Az előző oktatóanyagban bemutattuk, hogyan bővíthető ki az adatelérési réteg az adatbázis-tranzakciók támogatásához. Az adatbázis-tranzakciók garantálják, hogy egy adatmódosítási utasítássorozat egyetlen atomi műveletként lesz kezelve, ami biztosítja, hogy minden módosítás meghiúsuljon, vagy minden sikeres legyen. Miután ezen alacsony szintű DAL funkciókkal már végeztünk, készen állunk arra, hogy figyelmünket a kötegelt adatmódosítási felületek létrehozására fordítsuk.
Ebben az oktatóanyagban létrehozunk egy GridView-t, ahol minden sor szerkeszthető (lásd az 1. ábrát). Mivel minden sor a szerkesztőfelületén jelenik meg, nincs szükség Szerkesztés, Frissítés és Mégse gombok oszlopára. Ehelyett két Termékfrissítés gomb található a lapon, amelyek kattintáskor számba helyezik a GridView sorait, és frissítik az adatbázist.
A GridView minden sora szerkeszthető
1. ábra: A GridView minden sora szerkeszthető (ide kattintva megtekintheti a teljes méretű képet)
Lássunk hozzá!
Megjegyzés:
A Batch-frissítések végrehajtása oktatóanyagban létrehoztunk egy kötegszerkesztő felületet a DataList vezérlővel. Ez az oktatóanyag eltér az előzőtől, amelyben GridView-t használ, és a kötegfrissítés egy tranzakció hatókörén belül történik. Az oktatóanyag elvégzése után bátorítom, hogy térjen vissza a korábbi oktatóanyaghoz, és frissítse azt az adatbázis tranzakcióval kapcsolatos funkciók használatának bevezetésével, amelyeket az előző oktatóanyagban adtunk hozzá.
Az összes GridView-sor szerkeszthetővé tételének lépéseinek vizsgálata
Az adatok beszúrásának, frissítésének és törlésének áttekintésével kapcsolatos oktatóanyagban leírtak szerint a GridView beépített támogatást nyújt az alapul szolgáló adatok soronkénti szerkesztéséhez. A GridView belsőleg megjegyzi, hogy melyik sor szerkeszthető a tulajdonságánEditIndex keresztül. Mivel a GridView az adatforráshoz van kötve, ellenőrzi az egyes sorokat, hogy a sor indexe megegyezik-e az értékével EditIndex. Ha igen, akkor a sor s mezői a szerkesztőfelületükön jelennek meg. A BoundFields esetében a szerkesztőfelület egy TextBox, amelynek Text tulajdonsága a BoundField tulajdonsága DataField által megadott adatmező értékéhez van rendelve. A TemplateFields esetében a EditItemTemplate van a ItemTemplate helyett.
Ne feledje, hogy a szerkesztési munkafolyamat akkor indul el, amikor egy felhasználó a Sor szerkesztése gombra kattint. Ez egy postback-et eredményez, beállítja a GridView EditIndex tulajdonságát a kattintott sor indexére, és újraköti az adatokat a gridhez. Ha egy sor "Mégse" gombjára kattintanak, postback esetén először az EditIndex értéke -1-re lesz állítva, mielőtt az adatokat újrakötik a rácshoz. Mivel a GridView sorai nullánál kezdik az indexelést, a EditIndex-1 beállítása azt eredményezi, hogy a GridView olvasási módban jelenik meg.
A EditIndex tulajdonság jól működik a soronkénti szerkesztéshez, de nem kötegszerkesztéshez lett kialakítva. Ahhoz, hogy a teljes GridView szerkeszthető legyen, minden sor renderelésére a szerkesztőfelület használatával van szükség. Ennek legegyszerűbb módja, ha létrehoz egy sablonmezőt, ahol az egyes szerkeszthető mezők sablonmezőként vannak implementálva, a szerkesztési felület pedig a ItemTemplate.
A következő néhány lépésben létrehozunk egy teljesen szerkeszthető GridView-t. Az 1. lépésben a GridView és az ObjectDataSource létrehozásával kezdjük, és a BoundFields és a CheckBoxField mezőit sablonmezőkké alakítjuk. A 2. és a 3. lépésben áthelyezzük a szerkesztőfelületeket a TemplateFields EditItemTemplate helyről a ItemTemplate helyre.
1. lépés: Termékinformációk megjelenítése
Mielőtt létrehoznánk egy GridView-t, ahol szerkeszthetők a sorok, kezdjük a termékinformációk megjelenítésével. Nyissa meg a BatchUpdate.aspx lapot a BatchData mappában, és húzzon egy GridView-t az eszközkészletből a Tervezőre. Állítsa be a GridView ID-t ProductsGrid-re, és az intelligens címkéből válassza ki, hogy egy új ObjectDataSource-hoz kösse, amely a ProductsDataSource nevet kapja. Configureálja az ObjectDataSource-t, hogy az adatait az ProductsBLL osztály GetProducts függvényéből lekérje.
2. ábra: Az ObjectDataSource konfigurálása az ProductsBLL osztály használatára (kattintson ide a teljes méretű kép megtekintéséhez)
3. ábra: A termékadatok lekérése a GetProducts módszerrel (kattintson ide a teljes méretű kép megtekintéséhez)
A GridView-hoz hasonlóan az ObjectDataSource módosítási funkciói is úgy vannak kialakítva, hogy soronként működjenek. A rekordok frissítéséhez meg kell írnunk egy kis kódot a ASP.NET lap mögötti kódosztályában, amely kötegeli az adatokat, és átadja azokat a BLL-nek. Ezért állítsa az ObjectDataSource UPDATE, INSERT és DELETE lapjának legördülő listáit a (Nincs) értékre. A varázsló befejezéséhez kattintson a Befejezés gombra.
4. ábra: Állítsa a Drop-Down listákat az UPDATE, INSERT és DELETE tabulátorokban a (Nincs) értékre (ide kattintva megtekintheti a teljes méretű képet)
Az Adatforrás konfigurálása varázsló befejezése után az ObjectDataSource deklaratív korrektúrája az alábbihoz hasonlóan fog kinézni:
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>
Az Adatforrás konfigurálása varázsló befejezése azt is eredményezi, hogy a Visual Studio létrehozza a BoundFields és a CheckBoxField mezőket a GridView termékadatmezőihez. Ebben az oktatóanyagban csak a termék nevét, kategóriáját, árát és megszűnt állapotát tekintheti meg és szerkesztheti a felhasználó. Távolítsa el az összes mezőt a ProductName, CategoryName, UnitPrice és Discontinued kivételével, és nevezze át az első három mező HeaderText tulajdonságait Termékre, Kategóriára és Árat, sorrendben. Végül ellenőrizze a Lapozás engedélyezése és a Rendezés engedélyezése jelölőnégyzetet a GridView intelligens címkéjében.
Ezen a ponton a GridView három BoundFieldből áll (ProductName, CategoryName, és UnitPrice) és egy CheckBoxFieldből (Discontinued). Ezt a négy mezőt sablonmezőkké kell konvertálnunk, majd át kell helyeznünk a szerkesztőfelületet a TemplateField s-ről EditItemTemplate annak ItemTemplate.
Megjegyzés:
A TemplateFields létrehozását és testreszabását az Adatmódosítási felület testreszabása oktatóanyagban ismertettük. Végigvezetjük a BoundFields és a CheckBoxField sablonmezőkké alakításának lépésein, és meghatározzuk a szerkesztési felületeiket az ItemTemplate s-ben, de ha elakad, vagy frissítőre van szüksége, ne habozzon visszatérni a korábbi oktatóanyaghoz.
A GridView intelligens címkéjén kattintson az Oszlopok szerkesztése hivatkozásra a Mezők párbeszédpanel megnyitásához. Ezután jelölje ki az egyes mezőket, és kattintson a Mező konvertálása Sablonmező hivatkozássá.
5. ábra: A meglévő BoundFields és CheckBoxField átalakítása Sablonmezővé
Most, hogy minden mező egy TemplateField, készen állunk arra, hogy áthelyezzük a szerkesztőfelületet a EditItemTemplate mezőkből a ItemTemplate mezőkbe.
2. lépés: AProductNameUnitPrice kezelőfelületek létrehozása ésDiscontinuedszerkesztése
Ennek a lépésnek a témája a ProductName, UnitPriceés Discontinued a szerkesztési felületek létrehozása, és meglehetősen egyszerűek, mivel az egyes felületek már definiálva vannak a TemplateField s EditItemTemplate. A CategoryName szerkesztőfelület létrehozása egy kicsit nagyobb szerepet játszik, mivel létre kell hoznunk egy legördülő listát az alkalmazandó kategóriákról. Ezt a CategoryName szerkesztőfelületet a 3. lépés kezeli.
Kezdjük a ProductName TemplateFielddel. Kattintson a Sablonok szerkesztése hivatkozásra a GridView intelligens címkéről, és fúrja le a ProductName TemplateField EditItemTemplate-re. Jelölje ki a Szövegdobozt, másolja a vágólapra, majd illessze be a ProductName TemplateField s ItemTemplatefájlba. Módosítsa a TextBox tulajdonságát ID a következőre ProductName: .
Ezután adjon hozzá egy RequiredFieldValidatort a ItemTemplate-hez, hogy a felhasználó megadjon egy értéket minden termék nevéhez. Állítsa a ControlToValidate tulajdonságot ProductName értékre, a ErrorMessage tulajdonságnak Meg kell adnia a termék nevét. és a Text tulajdonságot *-ra állítani. Miután ezeket a kiegészítéseket elvégezte, a ItemTemplateképernyőnek a 6. ábrához hasonlóan kell kinéznie.
6. ábra: A ProductName TemplateField most tartalmaz egy szövegdobozt és egy RequiredFieldValidatort (ide kattintva megtekintheti a teljes méretű képet)
UnitPrice A szerkesztőfelülethez először másolja a Szövegdobozt EditItemTemplate-ból a ItemTemplate-ba. Ezután helyezzen egy $ értéket a Szövegdoboz elé, és állítsa a tulajdonságát ID UnitPrice értékre, a tulajdonságát Columns pedig 8-ra.
Adjon hozzá egy CompareValidatort is az UnitPrice s-hez ItemTemplate , hogy a felhasználó által megadott érték érvényes pénznemérték legyen 0,00 usd-nél nagyobb vagy egyenlő. Állítsa az érvényesítő ControlToValidate ingatlanját az UnitPrice értékre, az ErrorMessage ingatlanját pedig az Érvényes pénzértéket kell megadnia. Hagyja ki a pénznemszimbólumokat, tulajdonságát állítsa * értékre Text, Type-re Currency, Operator-re GreaterThanEqual, és 0-ra ValueToCompare.
7. ábra: CompareValidator hozzáadása annak ellenőrzéséhez, hogy a megadott ár nem negatív pénznemérték-e (kattintson ide a teljes méretű kép megtekintéséhez)
Discontinued A TemplateField esetében használhatja a már definiált jelölőnégyzetet a ItemTemplate. Egyszerűen állítsa a ID értéket Megszűnt státuszra, és a Enabled tulajdonságát állítsa a true értékre.
3. lépés: ACategoryNameszerkesztőfelület létrehozása
A TemplateField s CategoryName szerkesztőfelülete EditItemTemplate tartalmaz egy szövegmezőt, amely megjeleníti az CategoryName adatmező értékét. Ezt le kell cserélnünk egy legördülő listára, amely felsorolja a lehetséges kategóriákat.
Megjegyzés:
Az Adatmódosítási felület testreszabása oktatóanyag alaposabb és teljesebb beszélgetést tartalmaz egy sablon testreszabásáról, amely egy legördülő listát tartalmaz a Szövegdoboz helyett. Bár az itt ismertetett lépések teljesek, tömören vannak bemutatva. A kategóriák DropDownList-listájának létrehozásával és konfigurálásával kapcsolatos részletesebb információkért tekintse meg az Adatmódosítási felület testreszabása oktatóanyagot.
Húzzon egy DropDownList-et az eszközkészletből a CategoryName TemplateField ItemTemplate-jére, és állítsa be a ID értékét Categories-re. Ezen a ponton általában az intelligens címkén keresztül határozzuk meg a DropDownLists adatforrását, létrehozva egy új ObjectDataSource-t. Ez azonban hozzáadja az ObjectDataSource-t az ItemTemplateobjektumhoz, ami egy ObjectDataSource-példányt eredményez, amely minden GridView sorhoz létrejön. Ehelyett hozzuk létre az ObjectDataSource-t a GridView TemplateFieldsen kívül. Fejezze be a sablon szerkesztését, és húzzon egy ObjectDataSource-t az Eszközkészletből a ProductsDataSource ObjectDataSource alatti Tervezőre. Adja meg az új CategoriesDataSource ObjectDataSource nevét, és konfigurálja a CategoriesBLL osztály GetCategories metódusának használatára.
8. ábra: Az ObjectDataSource konfigurálása az CategoriesBLL osztály használatára (kattintson ide a teljes méretű kép megtekintéséhez)
9. ábra: A kategóriaadatok lekérése a GetCategories módszerrel (kattintson ide a teljes méretű kép megtekintéséhez)
Mivel ez az ObjectDataSource csupán adatok lekérésére szolgál, állítsa a legördülő listákat az UPDATE és a DELETE fülön a (Nincs) értékre. A varázsló befejezéséhez kattintson a Befejezés gombra.
10. ábra: Állítsa a Drop-Down listákat az UPDATE és a DELETE tabulátorokban a (Nincs) értékre (kattintson ide a teljes méretű kép megtekintéséhez)
A varázsló befejezése után a CategoriesDataSource deklaratív jelölőnyelv az alábbihoz hasonlóan fog kinézni:
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
Miután a CategoriesDataSource létre lett hozva és konfigurálva, térjen vissza a CategoryName sablonmezőkhöz ItemTemplate, és a Legördülő lista intelligens címkéjén kattintson az Adatforrás kiválasztása hivatkozásra. Az Adatforrás konfigurálása varázslóban válassza ki az első legördülő listában az CategoriesDataSource lehetőséget, és állítsa be úgy, hogy a CategoryName a megjelenítéshez, a CategoryID pedig értékként legyen használva.
11. ábra: A legördülő lista összekapcsolása a CategoriesDataSource (Kattintson ide a teljes méretű kép megtekintéséhez)
Ezen a ponton a Categories DropDownList felsorolja az összes kategóriát, de még nem választja ki automatikusan a Megfelelő kategóriát a GridView sorhoz kötött termékhez. Ehhez be kell állítani a Categories DropDownList s SelectedValue értékét a termék értékére CategoryID . Kattintson a DataBindings szerkesztése hivatkozásra a DropDownList intelligens címkéjén, és társítsa a SelectedValue tulajdonságot az adatmezővel a CategoryID 12. ábrán látható módon.
12. ábra: A termék értékének kötése CategoryID a DropDownLists tulajdonsághoz SelectedValue
Egy utolsó probléma továbbra is fennáll: ha a termék nem rendelkezik CategoryID megadott értékkel, akkor az adatkötési utasítás SelectedValue kivételt eredményez. Ennek az az oka, hogy a legördülő lista csak a kategóriák elemeit tartalmazza, és nem kínál lehetőséget azoknak a termékeknek, amelyeknek NULL adatbázis-értéke van CategoryID. A hiba kiküszöbölése érdekében állítsa be a DropDownList AppendDataBoundItems tulajdonságát true értékre, és adjon hozzá egy új elemet a DropDownListhez, kihagyva a Value tulajdonságot a deklaratív szintaxisból. Vagyis győződjön meg arról, hogy a Categories DropDownList deklaratív szintaxisa a következőhöz hasonlóan néz ki:
<asp:DropDownList ID="Categories" runat="server" AppendDataBoundItems="True"
DataSourceID="CategoriesDataSource" DataTextField="CategoryName"
DataValueField="CategoryID" SelectedValue='<%# Bind("CategoryID") %>'>
<asp:ListItem Value=">-- Select One --</asp:ListItem>
</asp:DropDownList>
Figyelje meg, hogy a <asp:ListItem Value=""> -- Select One - attribútuma Value explicit módon üres sztringre van állítva. Tekintse meg az Adatmódosítási felület testreszabása oktatóanyagot, amely részletesebben ismerteti, hogy miért van szükség erre a további DropDownList-elemre az NULL eset kezeléséhez, és miért elengedhetetlen a Value tulajdonság hozzárendelése egy üres sztringhez.
Megjegyzés:
Itt van egy lehetséges teljesítmény- és méretezhetőségi probléma, amelyet érdemes megemlíteni. Mivel minden sorhoz tartozik egy DropDownList, amely az CategoriesDataSource adatforrást használja, az CategoriesBLL osztály s GetCategories metódusát az oldallátogatásonként n-nek nevezzük, ahol n a GridView sorainak száma. Ezek az n hívások GetCategoriesn lekérdezést eredményeznek az adatbázisba. Ez az adatbázisra gyakorolt hatást csökkentheti, ha a visszaadott kategóriákat kérésenkénti gyorsítótárban vagy a gyorsítótárazási rétegen keresztül egy SQL-gyorsítótár-függőség vagy egy nagyon rövid időalapú lejárat használatával gyorsítótárazza.
4. lépés: A szerkesztőfelület befejezése
Számos módosítást végeztünk a GridView-sablonokon anélkül, hogy szüneteltettük volna az előrehaladást. Szánjon egy kis időt a haladás megtekintésére egy böngészőben. Ahogy a 13. ábrán látható, minden sort a cella szerkesztési felületét tartalmazó ItemTemplate elemmel jelenít meg.
13. ábra: Minden GridView-sor szerkeszthető (kattintson ide a teljes méretű kép megtekintéséhez)
Van néhány kisebb formázási probléma, amellyel jelenleg foglalkoznunk kell. Először vegye figyelembe, hogy az UnitPrice érték négy tizedesjegyet tartalmaz. A probléma megoldásához térjen vissza a UnitPrice TemplateField s-hez ItemTemplate , és a TextBox intelligens címkéjén kattintson a DataBindings szerkesztése hivatkozásra. Ezután adja meg, hogy a Text tulajdonságot számként kell formázni.
14. ábra: A tulajdonság formázása Text számként
Másodszor, középre helyezze a jelölőnégyzetet az Discontinued oszlopban (ahelyett, hogy balra igazítva lenne). Kattintson a GridView intelligens címkéjének Oszlop szerkesztése elemére, és válassza ki a Discontinued TemplateField elemet a bal alsó sarokban lévő mezők listájából. A 15. ábrán látható módon lépjen be a ItemStyle elembe, és állítsa a HorizontalAlign tulajdonságot középre.
15. ábra: A jelölőnégyzet középre igazítása Discontinued
Ezután vegyen fel egy ValidationSummary vezérlőt a lapra, és állítsa a ShowMessageBox tulajdonságát true értékre, és a ShowSummary tulajdonságát false értékre. Adja hozzá a gombweb vezérlőket is, amelyek kattintáskor frissítik a felhasználó módosításait. Pontosabban, adjon hozzá két gomb webvezérlőt, egyet a GridView fölé, egyet pedig alá úgy, hogy mindkét vezérlő tulajdonságait Text az 'Update Products' beállításra állítja.
Mivel a GridView szerkesztőfelülete a TemplateFields ItemTemplate s-ben van definiálva, az EditItemTemplate s-k feleslegesek, és törölhetők.
A fent említett formázási módosítások, a gombvezérlők hozzáadása és a szükségtelen EditItemTemplate sek eltávolítása után a lap deklaratív szintaxisának a következőképpen kell kinéznie:
<p>
<asp:Button ID="UpdateAllProducts1" runat="server" Text="Update Products" />
</p>
<p>
<asp:GridView ID="ProductsGrid" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ProductsDataSource"
AllowPaging="True" AllowSorting="True">
<Columns>
<asp:TemplateField HeaderText="Product" SortExpression="ProductName">
<ItemTemplate>
<asp:TextBox ID="ProductName" runat="server"
Text='<%# Bind("ProductName") %>'></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
ControlToValidate="ProductName"
ErrorMessage="You must provide the product's name."
runat="server">*</asp:RequiredFieldValidator>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Category"
SortExpression="CategoryName">
<ItemTemplate>
<asp:DropDownList ID="Categories" runat="server"
AppendDataBoundItems="True"
DataSourceID="CategoriesDataSource"
DataTextField="CategoryName"
DataValueField="CategoryID"
SelectedValue='<%# Bind("CategoryID") %>'>
<asp:ListItem>-- Select One --</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Price"
SortExpression="UnitPrice">
<ItemTemplate>
$<asp:TextBox ID="UnitPrice" runat="server" Columns="8"
Text='<%# Bind("UnitPrice", "{0:N}") %>'></asp:TextBox>
<asp:CompareValidator ID="CompareValidator1" runat="server"
ControlToValidate="UnitPrice"
ErrorMessage="You must enter a valid currency value.
Please omit any currency symbols."
Operator="GreaterThanEqual" Type="Currency"
ValueToCompare="0">*</asp:CompareValidator>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
<ItemTemplate>
<asp:CheckBox ID="Discontinued" runat="server"
Checked='<%# Bind("Discontinued") %>' />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
</Columns>
</asp:GridView>
</p>
<p>
<asp:Button ID="UpdateAllProducts2" runat="server" Text="Update Products" />
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProducts" TypeName="ProductsBLL">
</asp:ObjectDataSource>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
<asp:ValidationSummary ID="ValidationSummary1" runat="server"
ShowMessageBox="True" ShowSummary="False" />
</p>
A 16. ábrán ez a lap jelenik meg, ha a gombwebvezérlők hozzáadása és a formázás módosítása után egy böngészőben tekinti meg.
16. ábra: Az oldal most két frissítési termék gombot tartalmaz (kattintson ide a teljes méretű kép megtekintéséhez)
5. lépés: A termékek frissítése
Amikor egy felhasználó meglátogatja ezt a lapot, módosítja a módosításokat, majd a két Termék frissítése gomb egyikére kattint. Ezen a ponton valahogy menteni kell az egyes sorok felhasználó által megadott értékeit egy ProductsDataTable példányba, majd át kell adnunk egy BLL-metódusnak, amely ezt a példányt átadja ProductsDataTable a DAL metódusnak UpdateWithTransaction . Az UpdateWithTransactionelőző oktatóanyagban létrehozott módszer biztosítja, hogy a módosítások kötege atomi műveletként frissüljön.
Nevezze el a metódust BatchUpdate a(z) BatchUpdate.aspx.cs keretében és adja meg a következő kódot:
private void BatchUpdate()
{
// Enumerate the GridView's Rows collection and create a ProductRow
ProductsBLL productsAPI = new ProductsBLL();
Northwind.ProductsDataTable products = productsAPI.GetProducts();
foreach (GridViewRow gvRow in ProductsGrid.Rows)
{
// Find the ProductsRow instance in products that maps to gvRow
int productID = Convert.ToInt32(ProductsGrid.DataKeys[gvRow.RowIndex].Value);
Northwind.ProductsRow product = products.FindByProductID(productID);
if (product != null)
{
// Programmatically access the form field elements in the
// current GridViewRow
TextBox productName = (TextBox)gvRow.FindControl("ProductName");
DropDownList categories =
(DropDownList)gvRow.FindControl("Categories");
TextBox unitPrice = (TextBox)gvRow.FindControl("UnitPrice");
CheckBox discontinued =
(CheckBox)gvRow.FindControl("Discontinued");
// Assign the user-entered values to the current ProductRow
product.ProductName = productName.Text.Trim();
if (categories.SelectedIndex == 0)
product.SetCategoryIDNull();
else
product.CategoryID = Convert.ToInt32(categories.SelectedValue);
if (unitPrice.Text.Trim().Length == 0)
product.SetUnitPriceNull();
else
product.UnitPrice = Convert.ToDecimal(unitPrice.Text);
product.Discontinued = discontinued.Checked;
}
}
// Now have the BLL update the products data using a transaction
productsAPI.UpdateWithTransaction(products);
}
Ez a módszer úgy kezdődik, hogy az összes terméket visszajuttatjuk a ProductsDataTable-ba a BLL GetProducts metódusának hívásával. Ezután számba adja a ProductGrid GridView gyűjteményétRows. A Rows gyűjtemény a GridView-ban megjelenített összes sorhoz tartalmaz egyGridViewRow példányt. Mivel oldalanként legfeljebb tíz sort jelenítünk meg, a GridView gyűjteményének Rows legfeljebb tíz eleme lesz.
Minden sorhoz a ProductID elemet ragadják meg a DataKeys gyűjteményből, és a megfelelő ProductsRow elemet választják ki a ProductsDataTable gyűjteményből. A négy TemplateField bemeneti vezérlő programozottan hivatkozva vannak, és azok értékei a ProductsRow példány tulajdonságaihoz rendelhetők. Miután a GridView minden sora értékeit felhasználták a ProductsDataTable frissítéséhez, az átkerül a BLL UpdateWithTransaction metódusába, amely, ahogyan az előző oktatóanyagban láttuk, egyszerűen lehívja a DAL UpdateWithTransaction metódusát.
Az oktatóanyaghoz használt kötegfrissítési algoritmus frissíti a ProductsDataTable GridView egy sorának megfelelő sorokat, függetlenül attól, hogy a termék adatai módosultak-e. Bár az ilyen vak frissítések általában nem teljesítményproblémák, felesleges rekordokhoz vezethetnek, ha újra naplózzák az adatbázistábla módosításait. A Batch-frissítések végrehajtása oktatóanyagban egy kötegfrissítési felületet fedeztünk fel a DataList használatával, és olyan kódot adtunk hozzá, amely csak a felhasználó által ténylegesen módosított rekordokat frissíti. A Batch-frissítések végrehajtásának technikáival igény szerint frissítheti az oktatóanyagban szereplő kódot.
Megjegyzés:
Amikor az adatforrást intelligens címkén keresztül köti a GridView-hoz, a Visual Studio automatikusan hozzárendeli az adatforrás elsődleges kulcsértékét a GridView tulajdonságához DataKeyNames . Ha nem kötötte az ObjectDataSource-t a GridView-hoz az 1. lépésben ismertetett GridView intelligens címkén keresztül, akkor manuálisan kell beállítania a GridView tulajdonságát DataKeyNames ProductID értékre, hogy a gyűjteményen keresztül ProductID minden sor értékét elérhesseDataKeys.
A használt BatchUpdate kód hasonló a BLL-metódusokban UpdateProduct használt kódhoz, a fő különbség az, hogy a UpdateProduct metódusokban csak egyetlen ProductRow példány lesz lekérve az architektúrából. A ProductRow tulajdonságait kiosztó kód megegyezik a UpdateProducts metódusok és a foreach-beli BatchUpdate ciklus kódja között, ugyanúgy, mint az általános minta.
Ahhoz, hogy befejezzük az oktatóanyagot, meg kell hívnunk a BatchUpdate metódust, amikor bármelyik Termékek frissítése gombra kattintunk. Hozzon létre eseménykezelőket a Click két gombvezérlő eseményeihez, és adja hozzá a következő kódot az eseménykezelőkhöz:
BatchUpdate();
ClientScript.RegisterStartupScript(this.GetType(), "message",
"alert('The products have been updated.');", true);
Először hívást kezdeményeznek a BatchUpdate számára. Ezután a ClientScript property JavaScriptet injektáljuk, amely egy üzenetablakot jelenít meg, amely azt írja: A termékek frissítve lettek.
A kód tesztelése eltarthat egy percig. Látogasson el BatchUpdate.aspx egy böngészőbe, szerkessze a sorok számát, és kattintson a Termékek frissítése gomb egyikére. Feltételezve, hogy nincsenek bemeneti érvényesítési hibák, egy üzenetmezőnek kell megjelennie, amely azt a feliratot tartalmazza, hogy A termékek frissítve lettek. A frissítés atomiságának ellenőrzéséhez fontolja meg egy véletlenszerű CHECK kényszer hozzáadását, például az 1234,56-os értéket tiltó UnitPrice kényszert.
BatchUpdate.aspxEzután szerkesszen több rekordot, és ügyeljen arra, hogy a termék egyik értékét UnitPrice a tiltott értékre állítsa (1234,56). Ez hibát eredményezhet, amikor a Termékek frissítése gombra kattint, miközben az összetett művelet során a többi módosítás visszaáll az eredeti értékére.
AlternatívBatchUpdatemódszer
Az BatchUpdate imént megvizsgált módszer lekéri az összes terméket a BLL metódusából GetProducts , majd frissíti a GridView-ban megjelenő rekordokat. Ez a megközelítés akkor ideális, ha a GridView nem használ lapozást, de ha igen, akkor több száz, több ezer vagy több tízezer termék lehet, de csak tíz sor a GridView-ban. Ilyen esetben az adatbázis összes termékének csak 10 módosítására való lekérése nem ideális.
Az ilyen típusú helyzeteknél érdemes inkább a következő BatchUpdateAlternate módszert használni:
private void BatchUpdateAlternate()
{
// Enumerate the GridView's Rows collection and create a ProductRow
ProductsBLL productsAPI = new ProductsBLL();
Northwind.ProductsDataTable products = new Northwind.ProductsDataTable();
foreach (GridViewRow gvRow in ProductsGrid.Rows)
{
// Create a new ProductRow instance
int productID = Convert.ToInt32(ProductsGrid.DataKeys[gvRow.RowIndex].Value);
Northwind.ProductsDataTable currentProductDataTable =
productsAPI.GetProductByProductID(productID);
if (currentProductDataTable.Rows.Count > 0)
{
Northwind.ProductsRow product = currentProductDataTable[0];
// Programmatically access the form field elements in the
// current GridViewRow
TextBox productName = (TextBox)gvRow.FindControl("ProductName");
DropDownList categories =
(DropDownList)gvRow.FindControl("Categories");
TextBox unitPrice = (TextBox)gvRow.FindControl("UnitPrice");
CheckBox discontinued =
(CheckBox)gvRow.FindControl("Discontinued");
// Assign the user-entered values to the current ProductRow
product.ProductName = productName.Text.Trim();
if (categories.SelectedIndex == 0)
product.SetCategoryIDNull();
else
product.CategoryID = Convert.ToInt32(categories.SelectedValue);
if (unitPrice.Text.Trim().Length == 0)
product.SetUnitPriceNull();
else
product.UnitPrice = Convert.ToDecimal(unitPrice.Text);
product.Discontinued = discontinued.Checked;
// Import the ProductRow into the products DataTable
products.ImportRow(product);
}
}
// Now have the BLL update the products data using a transaction
productsAPI.UpdateProductsWithTransaction(products);
}
BatchMethodAlternate első lépésként hozzon létre egy új üres ProductsDataTable nevet products. Ezután végigmegy a GridView elemgyűjteményén Rows, és minden sorhoz megszerzi az adott termékinformációkat a BLL metódus GetProductByProductID(productID) használatával. A lekért ProductsRow példány tulajdonságai ugyanúgy frissülnek, mint a BatchUpdate. A sor frissítése után a products``ProductsDataTable metódus segítségével importálódik a ImportRow(DataRow)-be a DataTable-en keresztül.
foreach Miután a ciklus befejeződött, a products egy ProductsRow példányt tartalmaz a GridView minden sorához. Mivel minden ProductsRow példány hozzá lett adva a products (nem frissített) fájlhoz, ha vakon átadjuk a UpdateWithTransaction metódusnak, a ProductsTableAdapter rendszer megpróbálja beszúrni az egyes rekordokat az adatbázisba. Ehelyett meg kell határoznunk, hogy az egyes sorok módosultak (nem lettek hozzáadva).
Ez úgy érhető el, hogy a BLL-hez hozzáad egy új, UpdateProductsWithTransaction nevű metódust.
UpdateProductsWithTransaction, lásd alább, mindegyik RowState példány ProductsRow-beli ProductsDataTable-ját beállítja Modified értékre, majd átadja a ProductsDataTable-t a DAL UpdateWithTransaction metódusának.
public int UpdateProductsWithTransaction(Northwind.ProductsDataTable products)
{
// Mark each product as Modified
products.AcceptChanges();
foreach (Northwind.ProductsRow product in products)
product.SetModified();
// Update the data via a transaction
return UpdateWithTransaction(products);
}
Összefoglalás
A GridView beépített, soronkénti szerkesztési képességeket biztosít, de nem támogatja a teljes mértékben szerkeszthető felületek létrehozását. Ahogy ebben az oktatóanyagban láttuk, ezek a felületek lehetségesek, de egy kis munkát igényelnek. Ha olyan GridView-t szeretne létrehozni, amelyben minden sor szerkeszthető, át kell alakítanunk a GridView mezőit TemplateFieldsre, és meg kell határoznunk a szerkesztőfelületet az ItemTemplate s-ben. Emellett az Összes -type gomb webvezérlőjének frissítését is hozzá kell adni a laphoz, a GridView-tól elkülönítve. Ezeknek a Gombok Click eseménykezelőknek számba kell venniük a GridView gyűjteményét Rows , tárolniuk kell a módosításokat egy ProductsDataTable, és át kell adniuk a frissített információkat a megfelelő BLL-metódusnak.
A következő oktatóanyagban meg fogjuk nézni, hogyan hozhat létre felületet a tömeges törléshez. Minden GridView-sor tartalmaz egy jelölőnégyzetet, és az Összes -type frissítése gomb helyett a Kijelölt sorok törlése gombokat fogjuk használni.
Boldog programozást!
Tudnivalók a szerzőről
Scott Mitchell, hét ASP/ASP.NET-könyv szerzője és a 4GuysFromRolla.com alapítója, 1998 óta dolgozik a Microsoft webtechnológiáival. Scott független tanácsadóként, edzőként és íróként dolgozik. Legújabb könyve Sams Teach Yourself ASP.NET 2.0 24 óra alatt. Itt érhető el mitchell@4GuysFromRolla.com.
Külön köszönet
Ezt az oktatóanyag-sorozatot sok hasznos véleményező áttekintette. Az oktatóanyag vezető véleményezői Teresa Murphy és David Suru voltak. Szeretné áttekinteni a közelgő MSDN-cikkeimet? Ha igen, írj egy sort a mitchell@4GuysFromRolla.com-ra.