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
Ha a TableAdapter varázslóval létrehoz egy beírt adatkészletet, a megfelelő DataTable tartalmazza a fő adatbázis-lekérdezés által visszaadott oszlopokat. Vannak azonban olyan esetek, amikor a DataTable-nak további oszlopokat kell tartalmaznia. Ebben az oktatóanyagban megtudhatjuk, hogy miért ajánlott a tárolt eljárások használata, ha további DataTable-oszlopokra van szükségünk.
Bevezetés
Ha TableAdaptert ad hozzá egy gépelt adatkészlethez, a megfelelő DataTable-sémát a TableAdapter fő lekérdezése határozza meg. Ha például a fő lekérdezés A, B és C adatmezőket ad vissza, a DataTable három megfelelő oszlopot tartalmaz A, B és C néven. A TableAdapter a fő lekérdezésén kívül további lekérdezéseket is tartalmazhat, amelyek az adatok egy részhalmazát adja vissza valamilyen paraméter alapján. Például a ProductsTableAdapter fő lekérdezés mellett, amely az összes termékre vonatkozó információt ad vissza, olyan metódusokat is tartalmaz, mint GetProductsByCategoryID(categoryID) és GetProductByProductID(productID), amelyek adott termékinformációkat ad vissza egy megadott paraméter alapján.
A DataTable-séma a TableAdapter fő lekérdezését tükrözi, ha az összes TableAdapter-metódus ugyanazt vagy kevesebb adatmezőt ad vissza, mint a fő lekérdezésben megadottak. Ha egy TableAdapter metódusnak további adatmezőket kell visszaadnia, akkor ennek megfelelően bontsa ki a DataTable sémáját. A Master/Detail Using a Bulleted List of Master Records with a Details DataList oktatóanyagban hozzáadtunk egy metódust a CategoriesTableAdapter, amely visszaadta a CategoryID, CategoryName, és Description adatmezőket, amelyeket a fő lekérdezésben definiáltunk, plusz a NumberOfProducts adatmezőt, amely az egyes kategóriákhoz társított termékek számát jelentette. Manuálisan hozzáadtunk egy új oszlopot az CategoriesDataTable új metódus adatmező-értékének NumberOfProducts rögzítéséhez.
A Fájlok feltöltése oktatóanyagban leírtaknak megfelelően nagy gondot kell tenni az alkalmi SQL-utasításokat használó TableAdapters-ekkel, és olyan metódusokkal kell rendelkezniük, amelyek adatmezői nem felelnek meg pontosan a fő lekérdezésnek. Ha a TableAdapter Configuration varázsló újrafut, az összes TableAdapter-metódust frissíti, hogy az adatmezőlistája megegyezzék a fő lekérdezésével. Következésképpen a testreszabott oszloplistákkal rendelkező metódusok visszaállnak a fő lekérdezés oszloplistájára, és nem adják vissza a várt adatokat. Ez a probléma nem merül fel tárolt eljárások használatakor.
Ebben az oktatóanyagban azt vizsgáljuk meg, hogyan bővítheti ki a DataTable sémáját további oszlopokra. Az alkalmi SQL-utasítások használatakor a TableAdapter törékenysége miatt ebben az oktatóanyagban tárolt eljárásokat fogunk használni. A TableAdapter tárolt eljárások használatára való konfigurálásával kapcsolatos további információkért tekintse meg a Typed DataSet s TableAdapters oktatóanyag Új tárolt eljárások létrehozása című oktatóanyagát.
1. lépés: Oszlop hozzáadása aPriceQuartileProductsDataTable
A "Új tárolt eljárások létrehozása a Typed DataSet-ek táblagyorsítóihoz" című oktatóanyagban létrehoztunk egy Typed DataSet nevű NorthwindWithSprocs adathalmazt. Ez az adatkészlet jelenleg két Adattáblát tartalmaz: ProductsDataTable és EmployeesDataTable. A ProductsTableAdapter következő három módszer van:
-
GetProducts- a fő lekérdezés, amely a táblából származó összes rekordot visszaadjaProducts -
GetProductsByCategoryID(categoryID)- a megadott categoryID azonosítójú összes terméket visszaadja. -
GetProductByProductID(productID)- az adott terméket adja vissza a megadott termékazonosítóval.
A fő lekérdezés és a két további metódus ugyanazt az adatmezőkészletet adja vissza, nevezetesen a Products tábla összes oszlopát. Nincsenek korrelált lekérdezések vagy JOIN-k, amelyek kapcsolódó adatokat kérnek le a Categories vagy Suppliers táblákból. Ezért a ProductsDataTable táblázat minden mezőjéhez tartozik egy megfelelő oszlop a Products-ben.
Ebben az oktatóanyagban adjunk hozzá egy metódust az ProductsTableAdapter elnevezetthez GetProductsWithPriceQuartile , amely az összes terméket visszaadja. A szabványos termékadatmezők mellett a GetProductsWithPriceQuartile egy PriceQuartile adatmezőt is tartalmaz majd, amely azt jelzi, hogy a termék ára melyik kvartilis alá esik. Például azok a termékek, amelyek árai a legdrágább 25% közé esnek, 1 értékűek lesznek PriceQuartile, míg azok, amelyek árai az alsó 25% közé tartoznak, 4 értékűek lesznek. Mielőtt azonban elkészítenénk a tárolt eljárást ezeknek az információknak a visszaadására, először frissítenünk kell a ProductsDataTable-t, hogy tartalmazzon egy oszlopot a PriceQuartile eredmények tárolására, amikor a GetProductsWithPriceQuartile metódust alkalmazzuk.
Nyissa meg az NorthwindWithSprocs Adathalmazt, és kattintson a jobb gombbal a ProductsDataTablegombra. Válassza a helyi menüben a "Hozzáadás" lehetőséget, majd válassza ki az "Oszlop" opciót.
1. ábra: Új oszlop hozzáadása a ProductsDataTable képhez (kattintson ide a teljes méretű kép megtekintéséhez)
Ezzel új oszlopot ad hozzá a DataTable nevű Oszlop1 típusú adattáblához System.String. Frissítenünk kell az oszlop nevét PriceQuartile-ra, és a típusát System.Int32-ra, mivel az 1-től 4-ig terjedő szám tárolására fogjuk használni. Válassza ki az újonnan hozzáadott oszlopot a ProductsDataTable, majd a Tulajdonságok ablakban állítsa be a Name tulajdonságot PriceQuartile értékre, a DataType tulajdonságot pedig System.Int32 értékre.
2. ábra: Az Új oszlop és NameDataType tulajdonságok beállítása (ide kattintva megtekintheti a teljes méretű képet)
Ahogy a 2. ábrán látható, további tulajdonságok is beállíthatók, például hogy az oszlop értékeinek egyedinek kell-e lenniük, ha az oszlop automatikusan növekményes oszlop, engedélyezve vannak-e adatbázisértékek NULL , és így tovább. Hagyja meg ezeket az értékeket az alapértelmezett értékekkel.
2. lépés: AGetProductsWithPriceQuartilemetódus létrehozása
Most, hogy az ProductsDataTable frissítve lett a PriceQuartile oszlop beillesztésével, készen állunk a GetProductsWithPriceQuartile metódus létrehozására. Először kattintson a jobb gombbal a TableAdapterre, és válassza a Helyi menü Lekérdezés hozzáadása parancsát. Ekkor megjelenik a TableAdapter Lekérdezéskonfiguráció varázsló, amely először megkérdezi, hogy alkalmi SQL-utasításokat vagy új vagy meglévő tárolt eljárást szeretnénk-e használni. Mivel még nem rendelkezünk olyan tárolt eljárással, amely visszaadja az árkvartilis adatokat, engedélyezze a TableAdapternek, hogy létrehozhassa számunkra ezt a tárolt eljárást. Válassza az Új tárolt eljárás létrehozása lehetőséget, és kattintson a Tovább gombra.
3. ábra: Utasítsa a TableAdapter varázslót, hogy hozza létre a tárolt eljárást számunkra (kattintson ide a teljes méretű kép megtekintéséhez)
A következő, 4. ábrán látható képernyőn a varázsló megkérdezi, hogy milyen típusú lekérdezést szeretne hozzáadni. Mivel a GetProductsWithPriceQuartile metódus a Products tábla összes oszlopát és rekordját visszaadja, válassza a SELECT opciót, amely a sorokat adja vissza, majd kattintson a Tovább gombra.
4. ábra: A lekérdezés egy SELECT olyan utasítás lesz, amely több sort ad vissza (ide kattintva megtekintheti a teljes méretű képet)
Ezután megjelenik a SELECT lekérdezés kérése. Írja be a következő lekérdezést a varázslóba:
SELECT ProductID, ProductName, SupplierID, CategoryID,
QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
ReorderLevel, Discontinued,
NTILE(4) OVER (ORDER BY UnitPrice DESC) as PriceQuartile
FROM Products
A fenti lekérdezés az SQL Server 2005 új NTILE függvényével osztja el az eredményeket négy csoportra, ahol a csoportokat a UnitPrice csökkenő sorrendbe rendezett értékek határozzák meg.
Sajnos a Lekérdezésszerkesztő nem tudja, hogyan elemezheti a OVER kulcsszót, és hibaüzenet jelenik meg a fenti lekérdezés elemzésekor. Ezért írja be a fenti lekérdezést közvetlenül a varázsló szövegmezőjába a Lekérdezésszerkesztő használata nélkül.
Megjegyzés:
Az NTILE és az SQL Server 2005 egyéb rangsorolási függvényeivel kapcsolatos további információkért tekintse meg az SQL Server 2005 Books OnlineROW_NUMBER (Transact-SQL) és a Ranking Functions (Rangsorfüggvények) szakaszát.
Miután megadta a SELECT lekérdezést, és a Tovább gombra kattintott, a varázsló megkér minket, hogy adja meg a létrehozandó tárolt eljárás nevét. Nevezze el az új tárolt eljárást Products_SelectWithPriceQuartile , és kattintson a Tovább gombra.
5. ábra: A tárolt eljárás Products_SelectWithPriceQuartile elnevezése (kattintson ide a teljes méretű kép megtekintéséhez)
Végül a rendszer arra kéri, hogy nevezze el a TableAdapter metódusokat. Hagyja bejelölve a DataTable kitöltése és a DataTable visszaadása jelölőnégyzeteket, és nevezze el a metódusokat FillWithPriceQuartile és GetProductsWithPriceQuartile.
6. ábra: Nevezze el a TableAdapter metódusokat, és kattintson a Befejezés gombra (kattintson ide a teljes méretű kép megtekintéséhez)
Ha a SELECT lekérdezés meg van adva, és a tárolt eljárás és a TableAdapter metódus neve el van nevezve, kattintson a Befejezés gombra a varázsló befejezéséhez. Ekkor figyelmeztetést kaphat a varázslótól, amely szerint OVER az SQL-szerkezet vagy -utasítás nem támogatott. Ezek a figyelmeztetések figyelmen kívül hagyhatók.
A varázsló befejezése után a TableAdapternek tartalmaznia kell a FillWithPriceQuartile és GetProductsWithPriceQuartile metódusokat, és az adatbázisnak tartalmaznia kell egy Products_SelectWithPriceQuartile nevű tárolt eljárást. Szánjon egy kis időt annak ellenőrzésére, hogy a TableAdapter valóban tartalmazza-e ezt az új módszert, és hogy a tárolt eljárás helyesen lett-e hozzáadva az adatbázishoz. Az adatbázis ellenőrzésekor, ha nem látja a tárolt eljárást, kattintson a jobb gombbal a Tárolt eljárások mappára, és válassza a Frissítés lehetőséget.
7. ábra: Ellenőrizze, hogy új metódus lett-e hozzáadva a TableAdapterhez
8. ábra: Győződjön meg arról, hogy az adatbázis tartalmazza a Products_SelectWithPriceQuartile tárolt eljárást (kattintson ide a teljes méretű kép megtekintéséhez)
Megjegyzés:
Az alkalmi SQL-utasítások helyett a tárolt eljárások használatának egyik előnye, hogy a TableAdapter Configuration varázsló újrafuttatása nem módosítja a tárolt eljárások oszloplistáit. Ezt úgy ellenőrizheti, hogy a jobb gombbal a TableAdapterre kattint, a helyi menüBen a Konfigurálás lehetőséget választva elindítja a varázslót, majd a Befejezés gombra kattint a befejezéshez. Ezután nyissa meg az adatbázist, és tekintse meg a Products_SelectWithPriceQuartile tárolt eljárást. Vegye figyelembe, hogy az oszloplistája nem módosult. Ha alkalmi SQL-utasításokat használnánk, a TableAdapter konfigurációs varázsló újrafuttatása visszaállította volna ezt a lekérdezés oszloplistáját a fő lekérdezés oszloplistájának megfelelően, így eltávolítva a metódus által használt lekérdezésből az GetProductsWithPriceQuartile NTILE utasítást.
Az adatelérési réteg s GetProductsWithPriceQuartile metódusának meghívásakor a TableAdapter végrehajtja a Products_SelectWithPriceQuartile tárolt eljárást, és minden visszaadott rekordhoz ProductsDataTable hozzáad egy sort. Az adatmezők, amelyeket a tárolt eljárás visszaad, az ProductsDataTable oszlopaira vannak leképezve. Mivel a tárolt eljárásból visszaadott PriceQuartile adatmező értéke az ProductsDataTable oszlophoz van rendelve PriceQuartile.
Azon TableAdapter metódusok esetében, amelyek lekérdezései nem adnak vissza adatmezőt PriceQuartile , az PriceQuartile s oszlop értéke a tulajdonság által DefaultValue megadott érték. Ahogy a 2. ábrán látható, ez az érték az DBNullalapértelmezett érték. Ha egy másik alapértelmezett értéket szeretne, egyszerűen állítsa be a DefaultValue tulajdonságot ennek megfelelően. Csak győződjön meg arról, hogy az DefaultValue érték érvényes az DataType oszlop alapján (azaz System.Int32 a PriceQuartile oszlop esetében).
Ezen a ponton végrehajtottuk a szükséges lépéseket egy további oszlop DataTable-hoz való hozzáadásához. Annak ellenőrzéséhez, hogy ez a további oszlop a vártnak megfelelően működik-e, hozzunk létre egy ASP.NET oldalt, amely megjeleníti az egyes termékek nevét, árát és árkvartiliseit. Mielőtt azonban ezt tennénk, először frissíteni kell az üzleti logikai réteget, hogy belefoglaljunk egy metódust, amely lehívja a DAL metódust GetProductsWithPriceQuartile . Ezután a 3. lépésben frissítjük a BLL-t, majd létrehozzuk a ASP.NET lapot a 4. lépésben.
3. lépés: Az üzleti logikai réteg bővítése
Mielőtt a bemutató réteg új GetProductsWithPriceQuartile metódusát használnánk, először hozzá kell adnunk egy megfelelő metódust a BLL-hez. Nyissa meg az ProductsBLLWithSprocs osztályfájlt, és adja hozzá a következő kódot:
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Select, false)]
public NorthwindWithSprocs.ProductsDataTable GetProductsWithPriceQuartile()
{
return Adapter.GetProductsWithPriceQuartile();
}
A többi adatlekérési metódushoz ProductsBLLWithSprocshasonlóan a GetProductsWithPriceQuartile metódus egyszerűen meghívja a DAL s megfelelő GetProductsWithPriceQuartile metódust, és visszaadja az eredményeket.
4. lépés: Az árkvartilis információk megjelenítése egy ASP.NET weblapon
A BLL kiegészítésével készen állunk egy ASP.NET oldal létrehozására, amely az egyes termékek árkvartilisét jeleníti meg. Nyissa meg a AddingColumns.aspx lapot a AdvancedDAL mappában, és húzza a GridView-t az Eszköztárból a Tervezőbe, majd állítsa be a ID tulajdonságát Products értékre. A GridView intelligens címkéje alapján kösse hozzá egy új ObjectDataSource-hoz.ProductsDataSource Konfigurálja az ObjectDataSource-t az osztály s ProductsBLLWithSprocs metódusának GetProductsWithPriceQuartile használatára. Mivel ez egy írásvédett táblázat lesz, állítsa a legördülő listákat az UPDATE, INSERT és DELETE füleken a (Nincs) értékre.
9. ábra: Az ObjectDataSource konfigurálása az ProductsBLLWithSprocs osztály használatára (kattintson ide a teljes méretű kép megtekintéséhez)
10. ábra: Termékadatok lekérése a GetProductsWithPriceQuartile metódusból (kattintson ide a teljes méretű kép megtekintéséhez)
Az Adatforrás konfigurálása varázsló befejezése után a Visual Studio automatikusan hozzáad egy BoundField vagy CheckBoxField mezőt a GridView-hoz a metódus által visszaadott összes adatmezőhöz. Az egyik adatmező az PriceQuartile, amely az a ProductsDataTable oszlop, amit az 1. lépésben hozzáadtunk.
Szerkessze a GridView mezőit, és távolítsa el az összeset a ProductName, UnitPrice, és PriceQuartile BoundFields mezők kivételével. Konfigurálja a UnitPrice BoundFieldet úgy, hogy az értékét pénznemként formázza, és rendezze a UnitPrice és PriceQuartile BoundFieldeket rendre jobbra és középre. Végül frissítse a többi BoundFields HeaderText tulajdonságot a Product, Price és Price Quartile értékre. Emellett jelölje be a Rendezés engedélyezése jelölőnégyzetet a GridView intelligens címkéjén.
A módosítások után a GridView és az ObjectDataSource deklaratív korrektúrája az alábbihoz hasonlóan fog kinézni:
<asp:GridView ID="Products" runat="server" AllowSorting="True"
AutoGenerateColumns="False" DataKeyNames="ProductID"
DataSourceID="ProductsDataSource">
<Columns>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
HeaderText="Price" HtmlEncode="False"
SortExpression="UnitPrice">
<ItemStyle HorizontalAlign="Right" />
</asp:BoundField>
<asp:BoundField DataField="PriceQuartile" HeaderText="Price Quartile"
SortExpression="PriceQuartile">
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProductsWithPriceQuartile"
TypeName="ProductsBLLWithSprocs">
</asp:ObjectDataSource>
A 11. ábrán ez a lap jelenik meg, amikor egy böngészőben látogatják meg. Vegye figyelembe, hogy kezdetben a termékeket az áruk csökkenő sorrendben rendeli meg, és minden termék megfelelő PriceQuartile értéket kap. Természetesen ezek az adatok más feltételek szerint is rendezhetők, és az Ár kvartilis oszlop értéke továbbra is tükrözi a termék ár szerinti rangsorolását (lásd a 12. ábrát).
11. ábra: A termékeket az árak alapján rendezik (Kattintson ide a teljes méretű kép megtekintéséhez)
12. ábra: A termékeket a nevük alapján rendezik (ide kattintva megtekintheti a teljes méretű képet)
Megjegyzés:
Néhány sornyi kóddal bővíthetjük a GridView-t, hogy a terméksorokat a termékek PriceQuartile értéke alapján színezhesse. Ezeket a termékeket az első kvartilisben világoszöldre, a második kvartilisben világossárga színre színezhetjük, és így tovább. Javaslom, hogy szánjon egy kis időt arra, hogy hozzáadja ezt a funkciót. Ha frissítésre van szüksége a GridView formázásához, tekintse meg az Adatok alapján egyéni formázás oktatóanyagot.
Alternatív megközelítés – Másik TableAdapter létrehozása
Ahogy ebben az oktatóanyagban láttuk, amikor olyan metódust adunk hozzá egy TableAdapterhez, amely a fő lekérdezés által megadotttól eltérő adatmezőket ad vissza, a DataTable-hoz megfelelő oszlopokat adhatunk hozzá. Az ilyen megközelítés azonban csak akkor működik jól, ha a TableAdapterben kevés olyan metódus található, amely különböző adatmezőket ad vissza, és ha ezek az alternatív adatmezők nem változnak túl sokat a fő lekérdezéstől.
AHelyett, hogy oszlopokat ad hozzá a DataTable-hoz, ehelyett hozzáadhat egy másik TableAdaptert az adatkészlethez, amely az első TableAdapter metódusait tartalmazza, amelyek különböző adatmezőket adnak vissza. Ebben az oktatóanyagban ahelyett, hogy hozzáadnánk az PriceQuartile oszlopot a ProductsDataTable (csak a GetProductsWithPriceQuartile metódus által használt) oszlophoz, hozzáadhattunk volna egy további TableAdaptert ahhoz az adatkészlethez ProductsWithPriceQuartileTableAdapter , amely a Products_SelectWithPriceQuartile tárolt eljárást használta fő lekérdezésként. Azok az ASP.NET oldalak, amelyeknek szükségük volt a termékinformációkra az árkvartilissal együtt, a ProductsWithPriceQuartileTableAdapter-t használnák, míg azok, amelyeknek nem, továbbra is használhatják a ProductsTableAdapter-t.
Új TableAdapter hozzáadásával a DataTables változatlan marad, és oszlopai pontosan tükrözik a TableAdapter metódusaik által visszaadott adatmezőket. A további TableAdapters azonban ismétlődő feladatokat és funkciókat is bevezethet. Ha például azoknak az ASP.NET lapoknak, amelyek megjelenítik az PriceQuartile oszlopot, támogatniuk kell a beszúrást, frissítést és törlést, akkor a ProductsWithPriceQuartileTableAdapter-nak megfelelően kell konfigurálni az InsertCommand, UpdateCommand és DeleteCommand tulajdonságait. Bár ezek a tulajdonságok tükröznék az ProductsTableAdapter s-t, ez a konfiguráció egy további lépést vezet be. Emellett mostantól kétféleképpen frissíthet, törölhet vagy adhat hozzá egy terméket az adatbázishoz – az ProductsTableAdapter osztályokon ProductsWithPriceQuartileTableAdapter keresztül.
Az oktatóanyag letöltéséhez tartozik egy ProductsWithPriceQuartileTableAdapter osztály az NorthwindWithSprocs Adatkészletben, amely szemlélteti ezt az alternatív megközelítést.
Összefoglalás
A legtöbb esetben a TableAdapter összes metódusa ugyanazt az adatmezőkészletet adja vissza, de előfordulhat, hogy egy-két metódusnak egy további mezőt kell visszaadnia. Például a Master/Detail Using a Bulleted List of Master Records with a Details DataList oktatóanyagban hozzáadtunk egy metódust ahhoz, hogy a CategoriesTableAdapter fő lekérdezés adatmezői mellett egy NumberOfProducts mezőt is visszaadottunk, amely az egyes kategóriákhoz társított termékek számát jelentette. Ebben az oktatóanyagban egy olyan metódus hozzáadását vizsgáltuk meg, amely a ProductsTableAdapter fő lekérdezés adatmezői mellett egy PriceQuartile mezőt is visszaadott. A TableAdapter metódusok által visszaadott további adatmezők rögzítéséhez megfelelő oszlopokat kell hozzáadni a DataTable-hoz.
Ha manuálisan szeretne oszlopokat hozzáadni a DataTable-hoz, javasoljuk, hogy a TableAdapter tárolt eljárásokat használjon. Ha a TableAdapter alkalmi SQL-utasításokat használ, a TableAdapter Konfiguráció varázsló futtatásakor az összes metódus adatmezőlistájában visszaáll a fő lekérdezés által visszaadott adatmezőkre. Ez a probléma nem terjed ki a tárolt eljárásokra, ezért ajánlottak, és ebben az oktatóanyagban használták őket.
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 Tanuld meg ASP.NET 2.0 24 óra alatt. Ő itt elérhető 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 Randy Schmidt, Jacky Goor, Bernadette Leigh és Hilton Giesenow voltak. Szeretné áttekinteni a közelgő MSDN-cikkeimet? Ha igen, írj egy sort a mitchell@4GuysFromRolla.com-ra.