Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Autor : Scott Mitchell
W tym samouczku kontynuujemy nasze spojrzenie na kontrolkę SqlDataSource i dowiemy się, jak definiować zapytania sparametryzowane. Parametry można określić zarówno deklaratywnie, jak i programowo, i można je pobrać z wielu lokalizacji, takich jak ciąg zapytania, stan sesji, inne kontrolki i inne.
Wprowadzenie
W poprzednim samouczku pokazano, jak używać kontrolki SqlDataSource do pobierania danych bezpośrednio z bazy danych. Korzystając z kreatora konfiguracji źródła danych, możemy wybrać bazę danych, a następnie: wybrać kolumny do zwrócenia z tabeli lub widoku; wprowadzanie niestandardowej instrukcji SQL; lub użyj procedury składowanej. Niezależnie od tego, czy wybierasz kolumny z tabeli lub widoku, czy wprowadzasz niestandardową instrukcję SQL, właściwość formantu SelectCommand SqlDataSource s jest przypisywana do wynikowej instrukcji SQL SELECT ad hoc i to właśnie ta SELECT instrukcja jest wykonywana po wywołaniu metody SqlDataSource Select() (programowo lub automatycznie z formantu sieci Web danych).
W instrukcjach SQL SELECT użytych w poprzednich demonstracjach samouczka brakowało WHERE klauzul. W instrukcji SELECTWHERE klauzula może służyć do ograniczania zwracanych wyników. Na przykład, aby wyświetlić nazwy produktów kosztujących więcej niż 50,00 USD, możemy użyć następującego zapytania:
SELECT ProductName
FROM Products
WHERE UnitPrice > 50.00
Zazwyczaj wartości używane w klauzuli WHERE są określane przez pewne źródło zewnętrzne, takie jak wartość ciągu zapytania, zmienna sesji lub dane wejściowe użytkownika z formantu sieci Web na stronie. Idealnie byłoby, gdyby takie dane wejściowe były określane za pomocą parametrów. W programie Microsoft SQL Server parametry są oznaczane za pomocą @parameterName, na przykład:
SELECT ProductName
FROM Products
WHERE UnitPrice > @Price
SqlDataSource obsługuje sparametryzowane zapytania, zarówno dla SELECT instrukcji, jak i INSERT, UPDATEi DELETE instrukcji. Co więcej, wartości parametrów mogą być automatycznie pobierane z różnych źródeł: ciągu zapytania, stanu sesji, kontrolek na stronie i tak dalej, lub mogą być przypisywane programowo. W tym samouczku zobaczymy, jak definiować sparametryzowane zapytania, a także jak określać wartości parametrów zarówno deklaratywnie, jak i programowo.
Uwaga / Notatka
W poprzednim samouczku porównaliśmy ObjectDataSource, który był naszym narzędziem z wyboru w pierwszych 46 samouczkach z SqlDataSource, zwracając uwagę na ich podobieństwa koncepcyjne. Podobieństwa te rozciągają się również na parametry. Parametry ObjectDataSource są mapowane na parametry wejściowe metod w warstwie logiki biznesowej. W przypadku elementu SqlDataSource parametry są definiowane bezpośrednio w zapytaniu SQL. Obie kontrolki mają kolekcje parametrów dla swoich Select(), Insert(), i Update()Delete()metod, i obie mogą mieć te wartości parametrów wypełnione ze wstępnie zdefiniowanych źródeł (wartości ciągu zapytania, zmienne sesji itd.) lub przypisane programowo.
Tworzenie zapytania sparametryzowanego
Kreator konfiguracji źródła danych formantu SqlDataSource oferuje trzy sposoby definiowania polecenia, które ma zostać wykonane w celu pobrania rekordów bazy danych:
- Wybierając kolumny z istniejącej tabeli lub widoku,
- Wprowadzając niestandardową instrukcję SQL lub
- Wybierając procedurę składowaną
Podczas wybierania kolumn z istniejącej tabeli lub widoku parametry klauzuli WHERE muszą być określone w oknie dialogowym Dodawanie WHERE klauzuli. Jednak podczas tworzenia niestandardowej instrukcji SQL można wprowadzić parametry bezpośrednio do WHERE klauzuli (używając @parameterName do oznaczania każdego parametru). Procedura składowana składa się z jednej lub więcej instrukcji SQL, które można parametryzować. Parametry używane w instrukcjach SQL muszą być jednak przekazywane jako parametry wejściowe do procedury składowanej.
Ponieważ tworzenie zapytania sparametryzowanego zależy od tego, jak określono SqlDataSource s SelectCommand , przyjrzyjmy się wszystkim trzem podejściom. Aby rozpocząć, otwórz ParameterizedQueries.aspx stronę w folderze SqlDataSource , przeciągnij kontrolkę SqlDataSource z przybornika do projektanta i ustaw jej ID wartość na Products25BucksAndUnderDataSource. Następnie kliknij łącze Konfiguruj źródło danych w tagu inteligentnym formantu. Wybierz bazę danych, która ma być używana (NORTHWINDConnectionString) i kliknij przycisk Dalej.
Krok 1: Dodawanie klauzuli WHERE podczas wybierania kolumn z tabeli lub widoku
Podczas wybierania danych do zwrócenia z bazy danych za pomocą kontrolki SqlDataSource kreator konfiguracji źródła danych pozwala nam po prostu wybrać kolumny do zwrócenia z istniejącej tabeli lub widoku (patrz rysunek 1). Spowoduje to automatyczne utworzenie instrukcji SQL SELECT , która jest wysyłana do bazy danych po wywołaniu metody SqlDataSource Select() . Podobnie jak w poprzednim samouczku, wybierz tabelę Produkty z listy rozwijanej i sprawdź kolumny ProductID, ProductNamei UnitPrice .
Rysunek 1: Wybierz kolumny do zwrócenia z tabeli lub widoku (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Aby dołączyć WHERE klauzulę do instrukcji SELECT , kliknij przycisk, który powoduje wyświetlenie WHERE okna dialogowego Dodawanie WHERE klauzuli (patrz Rysunek 2). Aby dodać parametr ograniczający wyniki zwracane SELECT przez zapytanie, najpierw wybierz kolumnę, według której chcesz filtrować dane. Następnie wybierz operator, który ma być używany do filtrowania (=, <, <=, >i tak dalej). Na koniec wybierz źródło wartości parametru, na przykład z ciągu zapytania lub stanu sesji. Po skonfigurowaniu parametru kliknij przycisk Dodaj, aby uwzględnić go w SELECT zapytaniu.
W tym przykładzie niech s zwróci tylko te wyniki, w których UnitPrice wartość jest mniejsza lub równa 25,00 USD. W związku z tym wybierz UnitPrice z listy rozwijanej Kolumna i <= z listy rozwijanej Operator. W przypadku korzystania z zakodowanej na stałe wartości parametru (na przykład 25,00 USD) lub jeśli wartość parametru ma być określona programowo, wybierz opcję Brak z listy rozwijanej Źródło. Następnie wprowadź zakodowaną na stałe wartość parametru w polu tekstowym Wartość 25.00 i zakończ proces, klikając przycisk Dodaj.
Rysunek 2: Ograniczanie wyników zwracanych z okna dialogowego Dodaj WHERE klauzulę (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Po dodaniu parametru kliknij przycisk OK, aby powrócić do kreatora konfiguracji źródła danych. Instrukcja SELECT w dolnej części kreatora powinna teraz zawierać WHERE klauzulę z parametrem o nazwie @UnitPrice:
SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products]
WHERE ([UnitPrice] <= @UnitPrice)
Uwaga / Notatka
Jeśli określisz wiele warunków w klauzuli WHERE w oknie dialogowym Dodawanie WHERE klauzuli, kreator połączy je z operatorem AND . Jeśli musisz dołączyć an w OR klauzuli (na przykład WHERE), musisz skompilować instrukcję WHERE UnitPrice <= @UnitPrice OR Discontinued = 1SELECT za pomocą ekranu niestandardowej instrukcji SQL.
Zakończ konfigurowanie elementu SqlDataSource (kliknij przycisk Dalej, a następnie kliknij przycisk Zakończ), a następnie sprawdź znaczniki deklaratywne elementu SqlDataSource. Znacznik zawiera <SelectParameters> teraz kolekcję, która określa źródła parametrów w pliku .SelectCommand
<asp:SqlDataSource ID="Products25BucksAndUnderDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand=
"SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products] WHERE ([UnitPrice] <= @UnitPrice)">
<SelectParameters>
<asp:Parameter DefaultValue="25.00" Name="UnitPrice" Type="Decimal" />
</SelectParameters>
</asp:SqlDataSource>
Po wywołaniu metody SqlDataSource Select() s wartość parametru UnitPrice (25.00) jest stosowana do parametru @UnitPrice w SelectCommand przed wysłaniem do bazy danych. Wynik netto jest taki, że z tabeli zwracane są tylko te produkty, które są mniejsze Products lub równe 25,00 USD. Aby to potwierdzić, dodaj element GridView do strony, powiąż go z tym źródłem danych, a następnie wyświetl stronę za pomocą przeglądarki. Na liście powinny być widoczne tylko te produkty, których cena jest mniejsza lub równa 25,00 USD, jak pokazano na rysunku 3.
Rysunek 3: Wyświetlane są tylko produkty o wartości mniejszej lub równej 25,00 USD (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Krok 2: Dodawanie parametrów do niestandardowej instrukcji SQL
Podczas dodawania niestandardowej instrukcji SQL można jawnie wprowadzić klauzulę WHERE lub określić wartość w komórce Filtr w Konstruktorze zapytań. Aby to zademonstrować, wyświetlmy tylko te produkty w GridView, których ceny są mniejsze niż określony próg. Zacznij od dodania elementu TextBox do ParameterizedQueries.aspx strony, aby zebrać tę wartość progową od użytkownika. Ustaw właściwość s TextBox ID na wartość MaxPrice. Dodaj kontrolkę Przycisk sieci Web i ustaw jej Text właściwość na Wyświetl pasujące produkty .
Następnie przeciągnij element GridView na stronę i z jego tagu inteligentnego wybierz pozycję utworzenia nowego elementu SqlDataSource o nazwie ProductsFilteredByPriceDataSource. W kreatorze konfiguracji źródła danych przejdź do ekranu Określanie niestandardowej instrukcji SQL lub procedury składowanej (patrz Rysunek 4) i wprowadź następujące zapytanie:
SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice
Po wprowadzeniu zapytania (ręcznie lub za pośrednictwem Konstruktora zapytań) kliknij przycisk Dalej.
Rysunek 4: Zwróć tylko te produkty, które są mniejsze lub równe wartości parametru (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Ponieważ zapytanie zawiera parametry, następny ekran w kreatorze monituje nas o źródło wartości parametrów. Wybierz pozycję Formant z listy rozwijanej Źródło parametrów i MaxPrice (wartość kontrolki ID TextBox) z listy rozwijanej ControlID. Można również wprowadzić opcjonalną wartość domyślną, która będzie używana w przypadku, gdy użytkownik nie wprowadził żadnego tekstu w MaxPrice polu TextBox. Na razie nie wprowadzaj wartości domyślnej.
Rysunek 5: MaxPrice Właściwość TextBox Text s jest używana jako źródło parametrów (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Ukończ pracę kreatora konfiguracji źródła danych, klikając przycisk Dalej, a następnie przycisk Zakończ. Znaczniki deklaratywne dla elementów GridView, TextBox, Button i SqlDataSource są następujące:
Maximum price:
$<asp:TextBox ID="MaxPrice" runat="server" Columns="5" />
<asp:Button ID="DisplayProductsLessThanButton" runat="server"
Text="Display Matching Products" />
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
DataSourceID="ProductsFilteredByPriceDataSource" EnableViewState="False">
<Columns>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="Price"
HtmlEncode="False" DataFormatString="{0:c}"
SortExpression="UnitPrice" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="ProductsFilteredByPriceDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand=
"SELECT ProductName, UnitPrice
FROM Products WHERE UnitPrice <= @MaximumPrice">
<SelectParameters>
<asp:ControlParameter ControlID="MaxPrice" Name="MaximumPrice"
PropertyName="Text" />
</SelectParameters>
</asp:SqlDataSource>
Należy pamiętać, że parametr w sekcji SqlDataSource s <SelectParameters> to ControlParameter, który zawiera dodatkowe właściwości, takie jak ControlID i PropertyName. Po wywołaniu Select() metody SqlDataSource ControlParameter pobiera wartość z określonej właściwości formantu sieci Web i przypisuje ją do odpowiedniego parametru w pliku .SelectCommand W tym przykładzie MaxPrice właściwość s Text jest używana jako wartość parametru @MaxPrice .
Poświęć chwilę na wyświetlenie tej strony za pomocą przeglądarki. Podczas pierwszego odwiedzania strony lub za każdym razem, MaxPrice gdy w polu tekstowym brakuje wartości, w widoku GridView nie są wyświetlane żadne rekordy.
Rysunek 6: Nie są wyświetlane żadne rekordy, gdy MaxPrice pole tekstowe jest puste (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Powodem, dla którego żadne produkty nie są wyświetlane, jest to, że domyślnie pusty ciąg wartości parametru jest konwertowany na wartość bazy danych NULL . Ponieważ porównanie [UnitPrice] <= NULL zawsze daje w wyniku wartość False, nie są zwracane żadne wyniki.
Wprowadź wartość w polu tekstowym, na przykład 5,00, i kliknij przycisk Wyświetl pasujące produkty. Po ogłoszeniu zwrotnym element SqlDataSource informuje element GridView, że jedno ze źródeł parametrów uległo zmianie. W związku z tym GridView ponownie wiąże się z SqlDataSource, wyświetlając te produkty mniejsze lub równe 5,00 USD.
Rysunek 7: Wyświetlane są produkty o wartości mniejszej lub równej 5,00 USD (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Początkowe wyświetlanie wszystkich produktów
Zamiast wyświetlać brak produktów podczas pierwszego ładowania strony, możemy chcieć wyświetlić wszystkie produkty. Jednym ze sposobów wyświetlania listy wszystkich produktów, gdy MaxPrice pole tekstowe jest puste, jest ustawienie domyślnej wartości parametru na szalenie wysoką wartość, taką jak 1000000, ponieważ jest mało prawdopodobne, że Northwind Traders kiedykolwiek będzie mieć zapasy, których cena jednostkowa przekracza 1 000 000 USD. Jednak takie podejście jest krótkowzroczne i może nie działać w innych sytuacjach.
W poprzednich samouczkach - Parametry deklaratywne i Filtrowanie główne/szczegółowe za pomocą listy rozwijanej mieliśmy do czynienia z podobnym problemem. Naszym rozwiązaniem było umieszczenie tej logiki w warstwie logiki biznesowej. W szczególności BLL zbadał wartość przychodzącą i, jeśli była NULL to jakaś wartość zarezerwowana, wywołanie zostało przekierowane do metody DAL, która zwróciła wszystkie rekordy. Jeśli wartość przychodząca była normalną wartością filtrowania, wykonywano wywołanie metody DAL, która wykonywała instrukcję SQL, która używała sparametryzowanej WHERE klauzuli z podaną wartością.
Niestety, pomijamy architekturę podczas korzystania z SqlDataSource. Zamiast tego musimy dostosować instrukcję SQL, aby inteligentnie pobierać wszystkie rekordy, jeśli @MaximumPrice parametr jest NULL lub jakąś zarezerwowaną wartością. Na potrzeby tego ćwiczenia zróbmy to tak, że jeśli @MaximumPrice parametr jest równy -1.0, to mają zostać zwrócone wszystkie rekordy (-1.0 działa jako wartość zarezerwowana, ponieważ żaden produkt nie może mieć wartości ujemnej UnitPrice ). Aby to osiągnąć, możemy użyć następującej instrukcji SQL:
SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice OR @MaximumPrice = -1.0
Ta WHERE klauzula zwraca wszystkie rekordy, jeśli @MaximumPrice parametr jest równy -1.0. Jeśli wartość parametru nie -1.0jest równa , zwracane są tylko te produkty, których UnitPrice wartość jest mniejsza lub równa wartości parametru @MaximumPrice . Ustawiając domyślną wartość parametru @MaximumPrice na -1.0, przy pierwszym ładowaniu strony (lub zawsze, MaxPrice gdy pole TextBox jest puste), @MaximumPrice będzie miało wartość -1.0 i wszystkie produkty zostaną wyświetlone.
Rysunek 8: Teraz wszystkie produkty są wyświetlane, gdy MaxPrice pole tekstowe jest puste (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
W związku z tym podejściem należy zwrócić uwagę na kilka zastrzeżeń. Po pierwsze, należy zdać sobie sprawę, że typ danych parametru s jest wnioskowany na podstawie jego użycia w zapytaniu SQL. Jeśli zmienisz klauzulę WHERE z @MaximumPrice = -1.0 na @MaximumPrice = -1, środowisko uruchomieniowe traktuje parametr jako liczbę całkowitą. Jeśli następnie spróbujesz przypisać MaxPrice element TextBox do wartości dziesiętnej (na przykład 5,00 ), wystąpi błąd, ponieważ nie można przekonwertować liczby 5,00 na liczbę całkowitą. Aby temu zaradzić, upewnij się, że używasz @MaximumPrice = -1.0 w WHERE klauzuli lub, jeszcze lepiej, ustaw ControlParameter właściwość obiektu Type na dziesiętny .
Po drugie, dodając OR @MaximumPrice = -1.0 klauzulę do WHERE klauzuli, aparat zapytania nie może użyć indeksu on UnitPrice (zakładając, że taki istnieje), co powoduje skanowanie tabeli. Może to mieć wpływ na wydajność, Products jeśli w tabeli znajduje się wystarczająco duża liczba rekordów. Lepszym podejściem byłoby przeniesienie tej logiki do procedury składowanej, w której instrukcja IF wykonywałaby SELECT zapytanie z Products tabeli bez klauzuli, WHERE gdy wszystkie rekordy muszą zostać zwrócone, lub taką, której WHERE klauzula zawiera tylko UnitPrice kryteria, dzięki czemu można użyć indeksu.
Krok 3: Tworzenie i używanie sparametryzowanych procedur składowanych
Procedury składowane mogą zawierać zestaw parametrów wejściowych, które mogą być następnie używane w instrukcjach SQL zdefiniowanych w procedurze składowanej. Podczas konfigurowania elementu SqlDataSource do korzystania z procedury składowanej, która akceptuje parametry wejściowe, te wartości parametrów można określić przy użyciu tych samych technik, co w przypadku instrukcji SQL ad hoc.
Aby zilustrować korzystanie z procedur składowanych w SqlDataSource, utwórzmy nową procedurę składowaną w bazie danych Northwind o nazwie GetProductsByCategory, która akceptuje parametr o nazwie @CategoryID i zwraca wszystkie kolumny produktów, których CategoryID kolumna pasuje do @CategoryID. Aby utworzyć procedurę składowaną, przejdź do Eksploratora serwera i przejdź do NORTHWND.MDF szczegółów bazy danych. (Jeśli nie widzisz Eksploratora serwera, wyświetl go, przechodząc do menu Widok i wybierając opcję Eksplorator serwera).
W NORTHWND.MDF bazie danych kliknij prawym przyciskiem myszy folder Procedury składowane, wybierz polecenie Dodaj nową procedurę składowaną i wprowadź następującą składnię:
CREATE PROCEDURE dbo.GetProductsByCategory
(
@CategoryID int
)
AS
SELECT *
FROM Products
WHERE CategoryID = @CategoryID
Kliknij ikonę Zapisz (lub Ctrl+S), aby zapisać procedurę składowaną. Procedurę składowaną można przetestować, klikając ją prawym przyciskiem myszy w folderze Procedury składowane i wybierając polecenie Wykonaj. Spowoduje to wyświetlenie monitu o podanie parametrów procedury składowanej (@CategoryIDw tym przypadku), po których wyniki zostaną wyświetlone w oknie Dane wyjściowe.
Rysunek 9: Procedura GetProductsByCategory składowana po wykonaniu z wartością @CategoryID 1 (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Użyjmy tej procedury składowanej, aby wyświetlić wszystkie produkty w kategorii Napoje w widoku GridView. Dodaj nowy element GridView do strony i powiąż go z nowym elementem SqlDataSource o nazwie BeverageProductsDataSource. Przejdź do ekranu Określ niestandardową instrukcję SQL lub procedurę składowaną, wybierz przycisk radiowy Procedura składowana, a następnie wybierz procedurę GetProductsByCategory składowaną z listy rozwijanej.
Rysunek 10: Wybierz procedurę składowaną GetProductsByCategory z listy Drop-Down (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Ponieważ procedura składowana akceptuje parametr wejściowy (@CategoryID), kliknięcie przycisku Dalej powoduje wyświetlenie monitu o określenie źródła dla wartości tego parametru. Wartość Napoje CategoryID ma wartość 1, więc pozostaw listę rozwijaną Źródło parametru w pozycji Brak i wprowadź wartość 1 w polu tekstowym DefaultValue.
Rysunek 11: Użyj wartości Hard-Coded równej 1, aby zwrócić produkty z kategorii Napoje (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Jak pokazano w poniższym znaczniku deklaratywnym, w przypadku korzystania z procedury składowanej właściwość s SqlDataSource SelectCommand jest ustawiana na nazwę procedury składowanej, a właściwośćSelectCommandType jest ustawiana na StoredProcedure, co wskazuje, że SelectCommand jest to nazwa procedury składowanej, a nie instrukcji SQL ad hoc.
<asp:SqlDataSource ID="BeverageProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter DefaultValue="1" Name="CategoryID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
Przetestuj stronę w przeglądarce. Wyświetlane są tylko te produkty, które należą do kategorii Napoje, chociaż wszystkie pola produktu są wyświetlane, ponieważ procedura GetProductsByCategory składowana zwraca wszystkie kolumny z tabeli Products . Moglibyśmy oczywiście ograniczyć lub dostosować pola wyświetlane w widoku GridView z okna dialogowego Edytowanie kolumn widoku GridView.
Rysunek 12: Wszystkie napoje są wyświetlane (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Krok 4: Programowe wywoływanie instrukcji select() SqlDataSource
Przykłady, które widzieliśmy w poprzednim samouczku i tym samouczku do tej pory, powiązały kontrolki SqlDataSource bezpośrednio z elementem GridView. Dane kontrolki SqlDataSource można jednak programowo uzyskać do nich dostęp i wyliczyć je w kodzie. Może to być szczególnie przydatne, gdy trzeba wykonać zapytanie o dane w celu ich sprawdzenia, ale nie trzeba ich wyświetlać. Zamiast pisać cały kod standardowy ADO.NET celu nawiązania połączenia z bazą danych, określenia polecenia i pobrania wyników, możesz pozwolić, aby SqlDataSource obsłużył ten monotonny kod.
Aby zilustrować programową pracę z danymi SqlDataSource, wyobraź sobie, że Twój szef zwrócił się do Ciebie z prośbą o utworzenie strony internetowej, która wyświetla nazwę losowo wybranej kategorii i powiązanych z nią produktów. Oznacza to, że gdy użytkownik odwiedza tę stronę, chcemy losowo wybrać kategorię z Categories tabeli, wyświetlić nazwę kategorii, a następnie wyświetlić listę produktów należących do tej kategorii.
Aby to osiągnąć, potrzebujemy dwóch kontrolek SqlDataSource, jednej do pobrania losowej kategorii z tabeli Categories , a drugiej, aby uzyskać produkty kategorii. W tym kroku utworzymy SqlDataSource, który pobiera losowy rekord kategorii; Krok 5 dotyczy tworzenia elementu SqlDataSource, który pobiera produkty kategorii.
Zacznij od dodania elementu SqlDataSource do ParameterizedQueries.aspx i ustaw jego ID wartość .RandomCategoryDataSource Skonfiguruj go tak, aby używał następującego zapytania SQL:
SELECT TOP 1 CategoryID, CategoryName
FROM Categories
ORDER BY NEWID()
ORDER BY NEWID() Zwraca rekordy posortowane w kolejności losowej (patrz Używanie NEWID() do losowego sortowania rekordów).
SELECT TOP 1 Zwraca pierwszy rekord z zestawu wyników. Podsumowując, to zapytanie zwraca wartości kolumny CategoryID i CategoryName z jednej, losowo wybranej kategorii.
Aby wyświetlić wartość kategorii s CategoryName , dodaj do strony formant Label Web, ustaw jego ID właściwość na CategoryNameLabel, a następnie wyczyść jego Text właściwość. Aby programowo pobrać dane z kontrolki SqlDataSource, musimy wywołać jej Select() metodę.
MetodaSelect() oczekuje pojedynczego parametru wejściowego typu DataSourceSelectArguments, który określa, w jaki sposób dane powinny być komunikatowane przed ich zwróceniem. Może to obejmować instrukcje dotyczące sortowania i filtrowania danych i jest używane przez kontrolki sieci Web danych podczas sortowania lub stronicowania danych z kontrolki SqlDataSource. Jednak w naszym przykładzie nie musimy modyfikować danych przed ich zwróceniem, a zatem przekażemy DataSourceSelectArguments.Empty obiekt.
Metoda Select() zwraca obiekt, który implementuje IEnumerable. Dokładny zwracany typ zależy od wartości SqlDataSource właściwości kontrolkiDataSourceMode. Jak omówiono w poprzednim samouczku, tę właściwość można ustawić na wartość jednego lub DataSetDataReader. Jeśli jest ustawiona na DataSet, Select() metoda zwraca obiekt DataView ; jeśli jest ustawiona na DataReader, zwraca obiekt, który implementuje IDataReader.
RandomCategoryDataSource Ponieważ właściwość SqlDataSource jest DataSourceMode ustawiona na DataSet wartość (domyślnie), będziemy pracować z obiektem DataView.
Poniższy kod ilustruje sposób pobierania rekordów z RandomCategoryDataSource elementu SqlDataSource jako elementu DataView, a także sposobu odczytywania wartości kolumny CategoryName z pierwszego wiersza elementu DataView:
protected void Page_Load(object sender, EventArgs e)
{
// Get the data from the SqlDataSource as a DataView
DataView randomCategoryView =
(DataView)RandomCategoryDataSource.Select(DataSourceSelectArguments.Empty);
if (randomCategoryView.Count > 0)
{
// Assign the CategoryName value to the Label
CategoryNameLabel.Text =
string.Format("Here are Products in the {0} Category...",
randomCategoryView[0]["CategoryName"].ToString());
}
}
randomCategoryView[0] zwraca pierwszą DataRowView wartość w elemencie DataView.
randomCategoryView[0]["CategoryName"] Zwraca wartość kolumny CategoryName w tym pierwszym wierszu. Należy pamiętać, że element DataView jest luźno typowany. Aby odwołać się do określonej wartości kolumny, musimy przekazać nazwę kolumny jako ciąg znaków (w tym przypadku CategoryName). Rysunek 13 przedstawia komunikat wyświetlany w oknie dialogowym CategoryNameLabel podczas przeglądania strony. Oczywiście rzeczywista wyświetlana nazwa kategorii jest losowo wybierana przez RandomCategoryDataSource SqlDataSource przy każdej wizycie na stronie (w tym w ogłoszeniach zwrotnych).
Rysunek 13: Wyświetlana jest losowo wybrana nazwa kategorii (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Uwaga / Notatka
Gdyby właściwość formantu SqlDataSource s DataSourceMode została ustawiona na DataReaderwartość , wartość zwracana Select() przez metodę musiałaby zostać rzutowana na IDataReader. Aby odczytać wartość kolumny CategoryName z pierwszego wiersza, użyjemy kodu takiego jak:
if (randomCategoryReader.Read())
{
string categoryName = randomCategoryReader["CategoryName"].ToString();
...
}
Po losowym wybraniu kategorii przez SqlDataSource jesteśmy gotowi do dodania elementu GridView, który zawiera listę produktów kategorii.
Uwaga / Notatka
Zamiast używać kontrolki sieci Web Label do wyświetlania nazwy kategorii, mogliśmy dodać element FormView lub DetailsView do strony, wiążąc go z elementem SqlDataSource. Użycie etykiety pozwoliło nam jednak zbadać, jak programowo wywołać instrukcję Select() SqlDataSource i pracować z jej wynikowymi danymi w kodzie.
Krok 5: Programowe przypisywanie wartości parametrów
We wszystkich przykładach, które widzieliśmy do tej pory w tym samouczku, użyto zakodowanej na stałe wartości parametru lub wartości pobranej z jednego ze wstępnie zdefiniowanych źródeł parametrów (wartość ciągu zapytania, kontrolka sieci Web na stronie itd.). Jednak parametry kontrolki SqlDataSource można również ustawić programowo. Aby ukończyć nasz bieżący przykład, potrzebujemy SqlDataSource, który zwraca wszystkie produkty należące do określonej kategorii. Ten SqlDataSource będzie miał parametr, CategoryID którego wartość należy ustawić na podstawie wartości kolumny zwróconej CategoryID przez RandomCategoryDataSource SqlDataSource w procedurze Page_Load obsługi zdarzeń.
Zacznij od dodania elementu GridView do strony i powiąż go z nowym elementem SqlDataSource o nazwie ProductsByCategoryDataSource. Podobnie jak w kroku 3, skonfiguruj SqlDataSource tak, aby wywoływał procedurę GetProductsByCategory składowaną. Pozostaw listę rozwijaną Źródło parametrów ustawioną na Brak, ale nie wprowadzaj wartości domyślnej, ponieważ ustawimy tę wartość domyślną programowo.
Rysunek 14: Nie określaj źródła parametrów ani wartości domyślnej (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Po zakończeniu pracy kreatora SqlDataSource wynikowy znacznik deklaratywny powinien wyglądać podobnie do następującego:
<asp:SqlDataSource ID="ProductsByCategoryDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter Name="CategoryID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
Możemy przypisać DefaultValue parametr CategoryID programowo w procedurze Page_Load obsługi zdarzeń:
// Assign the ProductsByCategoryDataSource's
// CategoryID parameter's DefaultValue property
ProductsByCategoryDataSource.SelectParameters["CategoryID"].DefaultValue =
randomCategoryView[0]["CategoryID"].ToString();
Dzięki temu dodatkowi strona zawiera widok GridView, który pokazuje produkty skojarzone z losowo wybraną kategorią.
Rysunek 15: Nie określaj źródła parametrów ani wartości domyślnej (kliknij, aby wyświetlić obraz w pełnym rozmiarze)
Podsumowanie
SqlDataSource umożliwia deweloperom stron definiowanie sparametryzowanych zapytań, których wartości parametrów mogą być zakodowane na stałe, pobrane ze wstępnie zdefiniowanych źródeł parametrów lub przypisane programowo. W tym samouczku pokazano, jak utworzyć zapytanie sparametryzowane za pomocą kreatora konfigurowania źródła danych zarówno dla zapytań SQL ad hoc, jak i procedur składowanych. Przyjrzeliśmy się również użyciu zakodowanych na stałe źródeł parametrów, kontrolki sieci Web jako źródła parametrów i programowemu określaniu wartości parametru.
Podobnie jak w przypadku elementu ObjectDataSource, element SqlDataSource zapewnia również możliwości modyfikowania danych bazowych. W następnym samouczku przyjrzymy się, jak definiować INSERTinstrukcje , UPDATEi DELETE za pomocą SqlDataSource. Po dodaniu tych instrukcji możemy korzystać z wbudowanych funkcji wstawiania, edytowania i usuwania nieodłącznie związanych z kontrolkami GridView, DetailsView i FormView.
Szczęśliwe programowanie!
Informacje o autorze
Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Można go uzyskać pod adresem mitchell@4GuysFromRolla.com.
Specjalne podziękowania
Ta seria samouczków została omówiona przez wielu przydatnych recenzentów. Głównymi recenzentami tego samouczka byli Scott Clyde, Randell Schmidt i Ken Pespisa. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, napisz do mnie na adres mitchell@4GuysFromRolla.com.
@CategoryID równą 1" />