LINQ w ASP.NET
Transkrypt
LINQ w ASP.NET
ITA-103 Aplikacje Internetowe Piotr Bubacz Moduł 9 Wersja 1 LINQ w ASP.NET Spis treści LINQ w ASP.NET .................................................................................................................................. 1 Informacje o module ........................................................................................................................... 2 Przygotowanie teoretyczne................................................................................................................. 3 Przykładowy problem ................................................................................................................. 3 Podstawy teoretyczne ................................................................................................................. 3 Uwagi dla studenta ..................................................................................................................... 5 Dodatkowe źródła informacji ...................................................................................................... 6 Laboratorium podstawowe ................................................................................................................. 7 Problem 1 (czas realizacji 10 min) ............................................................................................... 7 Problem 2 (czas realizacji 15 min) ............................................................................................... 8 Problem 3 (czas realizacji 10 min) ............................................................................................... 9 Problem 4 (czas realizacji 10 min) ............................................................................................. 10 Piotr Bubacz ITA-103 Aplikacje Internetowe Moduł 9 LINQ w ASP.NET Informacje o module Opis modułu W tym module znajdziesz informacje dotyczące technologii LINQ. Nauczysz się, jak formułowad proste zapytania z wykorzystaniem zintegrowanego języka zapytao i w jaki sposób połączyd go z ASP.NET. Cel modułu Celem modułu jest przedstawienie technologii LINQ i możliwości jego wykorzystania w aplikacjach ASP.NET. Uzyskane kompetencje Po zrealizowaniu modułu będziesz: wiedział czym jest i jak działa LINQ potrafił tworzyd proste zapytania w LINQ potrafił wykorzystywad LINQ w ASP.NET Wymagania wstępne Przed przystąpieniem do pracy z tym modułem powinieneś: znad podstawy języka XHTML znad zasady pracy w środowisku Visual Studio, w szczególności tworzenia stron internetowych znad podstawy pracy z danymi w ASP.NET Mapa zależności modułu Zgodnie z mapą zależności przedstawioną na Rys. 1, przed przystąpieniem do realizacji tego modułu należy zapoznad się z materiałem zawartym w modułach „Podstawy HTML”, „Kaskadowe Arkusze Stylów – CSS”, „Wprowadzenie do ASP.NET” oraz „Kontrolki danych w ASP.NET”. MODUŁ 14 MODUŁ 13 MODUŁ 1 MODUŁ 12 MODUŁ 11 MODUŁ 2 MODUŁ 9 MODUŁ 10 MODUŁ 3 MODUŁ 4 MODUŁ 8 MODUŁ 5 MODUŁ 6 Rys. 1 Mapa zależności modułu Strona 9-2 Piotr Bubacz ITA-103 Aplikacje Internetowe Moduł 9 LINQ w ASP.NET Przygotowanie teoretyczne Przykładowy problem Większośd projektowanych programów manipuluje danymi w taki czy inny sposób. Dane są najczęściej przechowywane w relacyjnych bazach danych. Mimo to jest duża różnica między nowoczesnymi językami programowania a bazami w sposobie, w jaki reprezentują dane. Największą różnica tkwi w sposobie odwoływania się do danych w bazie. Pogram odwołuje się do bazy za pomocą API, które wymaga, aby zapytania były przesłane jako ciągi znaków. Niestety nie mam możliwości weryfikacji poprawności tworzonych zapytao w czasie kompilacji, a jedynie w czasie wykonania. Co więcej różnica, ta jest jeszcze bardziej widoczna przy odbieraniu wyników. Nowoczesne języki programowania przechowują dane w postaci obiektów, natomiast bazy danych organizują je w wiersze. Dotychczas połączenie tych dwóch światów należało do programisty osobno w każdej tworzonej aplikacji. Najlepszym rozwiązaniem było użycie pośredniej abstrakcyjnej warstwy dostępu, która umożliwiała przejście pomiędzy światem wierszy a światem obiektów. Podstawy teoretyczne Rozwiązaniem problemu niekompatybilności świata baz danych i nowoczesnych języków programowania jest LINQ (ang. Language Integrated Query), nowe podejście dostępu do danych, które integruje język zapytao bazodanowych bezpośrednio w językach programowania .NET. W wyniku otrzymujemy nie wiersze, ale obiekty. Korzyści: niezależnośd od typu danych operowanie na danych jak na obiektach lepsza integracja z językami programowania wsparcie dla IntelliSense Na Rys. 2 została przedstawiona architektura i komponenty LINQ.W warstwie najbliższej klientowi mamy języki programowania dostępne na platformie .NET, takie jak C# 3.0. Następnie mamy warstwę pośrednią, wykorzystywaną do translacji zapytao formułowanych w językach programowania z jednej strony, z drugiej zaś translacji danych z różnych źródeł na obiekty. .NET Language Integrated Query <book> <title/> <author/> <year/> <price/> </book> Rys. 2 Architektura i komponenty LINQ Strona 9-3 Piotr Bubacz ITA-103 Aplikacje Internetowe Moduł 9 LINQ w ASP.NET Operatory W LINQ możemy używad wielu operatorów. Najważniejsze z nich zostały przedstawione w Tab. 1. Tab. 1 Rodzaje operatorów w LINQ Rodzaj operacji Nazwa operatora filtrowanie Where projekcja Select, SelectMany kolejnośd OrderBy, ThenBy grupowanie GroupBy kwalifikatory Any, All partycje Take, Skip, TakeWhile, SkipWhile zbiory Distinct, Union, Intersect, Except elementy First, FirstOrDefault, ElementAt agregacja Count, Sum, Min, Max, Average konwersja ToArray, ToList, ToDictionary rzutowanie OfType<T> LINQ to XML W przypadku odwoływania się do dokumentów zapisanych w XML, wykorzystujemy warstwę pośrednią LINQ to XML. Porównajmy kod aplikacji do tworzenia dokumentu XML z wyników poszukiwania innego dokumentu XML. W wyniku chcemy otrzymad następującą listę osób mieszkających w USA: <contacts> <contact> <name>Great Lakes Food</name> <phone>(503) 555-7123</phone> </contact> ... </contacts> W przypadku programowania bez użycia LINQ napiszemy: XmlDocument doc = new XmlDocument(); XmlElement contacts = doc.CreateElement("contacts"); foreach (Customer c in customers) if (c.Country == "USA") { XmlElement e = doc.CreateElement("contact"); XmlElement name = doc.CreateElement("name"); name.InnerText = c.CompanyName; e.AppendChild(name); XmlElement phone = doc.CreateElement("phone"); phone.InnerText = c.Phone; e.AppendChild(phone); contacts.AppendChild(e); } doc.AppendChild(contacts); Używając LINQ: XElement contacts = new XElement("contacts", from c in customers Strona 9-4 Piotr Bubacz ITA-103 Aplikacje Internetowe Moduł 9 LINQ w ASP.NET where c.Country == "USA" select new XElement("contact", new XElement("name", c.CompanyName), new XElement("phone", c.Phone) ) ); Porównanie obu fragmentów zostało przedstawione w Tab. 2. Tab. 2 Porównanie programowania XML z i bez użycia LINQ Programowanie XML bez LINQ Programowanie XML z użyciem LINQ model imperatywny bazowanie na dokumencie brak wbudowanych zapytao wymaga dużej pamięci model deklaratywny bazowanie na elemencie zintegrowane zapytania mniejsze i szybsze LINQ to SQL Na Rys. 3 przedstawiono działanie zapytania do bazy zdefiniowanego w LINQ. Programista tworzy zapytanie w zintegrowanym języku wyrażeo, które warstwa pośrednia zamienia na zapytanie SQL. Zapytanie SQL jest przesyłane do bazy, skąd wracają wiersze. Następnie wiersze są przetwarzane na obiekty i udostępniane aplikacji. Podobnie jest w przypadku dodawania informacji do bazy. Rys. 3 LINQ to SQL Podsumowanie W tym rozdziale przedstawione zostały podstawy języka LINQ. Uwagi dla studenta Jesteś przygotowany do realizacji laboratorium jeśli: rozumiesz jak działa LINQ umiesz napisad proste zapytanie wykorzystując zintegrowany język zapytao Pamiętaj o zapoznaniu się z uwagami i poradami zawartymi w tym module. Upewnij się, że rozumiesz omawiane w nich zagadnienia. Jeśli masz trudności ze zrozumieniem tematu zawartego w uwagach, przeczytaj ponownie informacje z tego rozdziału i zajrzyj do notatek z wykładów. Strona 9-5 Piotr Bubacz ITA-103 Aplikacje Internetowe Moduł 9 LINQ w ASP.NET Dodatkowe źródła informacji 1. Fabrice Marguerie, Steve Eichert, Jim Wooley, LINQ in Action, Manning Publications, 2008 Autor w prosty sposób przybliża zagadnienia związane z LINQ. Warto też zajrzed na stronę książki http://linqinaction.net, gdzie autor umieszcza różne informacje na temat LINQ. 2. Jacek Matulewski, C# 3.0 i .NET 3.5. Technologia LINQ, Helion, 2008 Dzięki temu podręcznikowi nauczysz się pobierad dane z różnego rodzaju źródeł, tworzyd pliki XML w nowy, bardziej intuicyjny sposób, stosowad składowane rozszerzenia oraz nowego typu metody (oraz odpowiadające im operatory), zdefiniowane w najnowszej wersji języka C#. Ponadto dowiesz się, jak tworzyd własne źródła danych LINQ. 3. Paolo Pialorsi, Marco Russo, Introducing Microsoft LINQ, Microsoft Press, 2008 Książka stanowi wprowadzenie do LINQ dla osób, które nie miały wcześniejszego doświadczenia ani z tą technologią, ani z nowościami wprowadzonymi w C# 3.0. W zwięzły sposób omawia podstawy LINQ, w tym składnię, operatory i posługiwanie się tą technologią w odniesieniu do kolekcji obiektów, relacyjnych baz danych i dokumentów XML. Strona 9-6 Piotr Bubacz ITA-103 Aplikacje Internetowe Moduł 9 LINQ w ASP.NET Laboratorium podstawowe Problem 1 (czas realizacji 10 min) Aplikacja, która tworzysz dla Adventure Works wymaga rozszerzeo. Przede wszystkim Twojemu klientowi zależy na wyświetlaniu obrazków produktów. Twoim zadaniem jest zaimplementowanie sposobu pobierania obrazków z bazy danych. Zadanie Tok postępowania 1. Dodaj nową stronę Otwórz stronę przygotowaną w poprzednim dwiczeniu. Do aplikacji dodaj nową stronę Miniatura.aspx opartą o szablon strony SzablonStrony.master 2. Na podstawie parametru ID wyślij obrazek W metodzie Page_Load dodaj następujący kod: 3. Zapis i przetestuj dodaną funkcjonalnośd Zapisz zmiany w projekcie. Wyświetl stronę Miniatura.aspx i sprawdź, co jest wyświetlane. if (Request.QueryString["id"] != null) { AdventureWorksDataContext db = new AdventureWorksDataContext(); var miniaturka = (from p in db.Products where p.ProductID == int.Parse(Request.QueryString["id"]) select p.ThumbNailPhoto).FirstOrDefault(); if (miniaturka != null) { Response.ContentType = "image/bmp"; Response.BinaryWrite(miniaturka.ToArray()); } } Dlaczego pojawiła się pusta strona? Dodaj do adresu strony ?id=771. Co się zmieniło? Dlaczego? 4. Dodaj wyświetlanie obrazka na stronie Produkty.aspx Otwórz stronę Produkty.aspx. W widoku Design wybierz kontrolkę GridView, a następnie kilknij Smart Tag. Wybierz Edit Columns. Z listy Available Fields wybierz ImageField i kliknij Add. Przesuo pole na pierwszą pozycję korzystając z przycisku W obszarze ImageField Properties: — — — — 5. Zapisz i przetestuj dodaną funkcjonalnośd . w polu DataAlternateTextField wpisz Name w polu DataAlternateTextFormatString wpisz Miniatura {0} w polu DataImageUrlField wpisz ProductID w polu DataImageUrlFormatString wpisz ~/Miniatura.aspx?id={0} Zapisz zmiany w projekcie. Wyświetl stronę Produkty.aspx i sprawdź, czy wyświetlane są miniatury produktów. Strona 9-7 Piotr Bubacz ITA-103 Aplikacje Internetowe Moduł 9 LINQ w ASP.NET Problem 2 (czas realizacji 15 min) Teraz musisz przygotowad stronę wyświetlającą szczegóły produktu – Szczegoly.aspx. Zadanie Tok postępowania 1. Przygotuj stronę Szczegoly.aspx do wyświetlenia informacji o produkcie Do aplikacji dodaj stronę Szczegoly.aspx opartą na stronie wzorcowej, a następnie dodaj do niej kontrolkę MultiView, a następnie dwie kontrolki View o ID: prawidlowyView i blednyView. W pierwszej kontrolce umieśd kontrolkę Label i w oknie Properties w polu (ID) wpisz nazwaLabel, natomiast pole Text zostaw puste. Dodaj znacznik <br /> i dodaj kontrolkę Image i w oknie Properties w polu (ID) wpisz produktImage. Dodaj znacznik <br /> i napisz Kategoria:, a następnie umieśd kontrolkę Label i w oknie Properties w polu (ID) wpisz kategoriaLabel, natomiast pole Text zostaw puste. Dodaj znacznik <br /> i napisz Cena:, a następnie umieśd kontrolkę Label o właściwościach ID="cenaLabel" i Text="". Dodaj znacznik <br /> i napisz Kolor:, a następnie umieśd kontrolkę Label i w oknie Properties w polu (ID) wpisz kolorLabel, natomiast pole Text zostaw puste. Dodaj znacznik <br /> i napisz Opis:, a następnie dodaj znacznik <br /> i umieśd kontrolkę Label i w oknie Properties w polu (ID) wpisz opisLabel. W kontrolce blednyView w widoku Source dodaj: Nieprawidłowy produkt<br /> Na koocu w widoku Source dodaj: <a href="Produkty.aspx">Powrót do przeglądania produktów</a> 2. Wyświetl produkt zgodnie z przesłaną informacją przez metodę GET Do metody Page_Load dodaj: MultiView1.SetActiveView(blednyView); if (Request.QueryString["id"] != null) { AdventureWorksDataContext db = new AdventureWorksDataContext(); var produkt = (from p in db.Products where p.ProductID == int.Parse(Request.QueryString["id"]) select new { ProductID = p.ProductID, Name = p.Name, Category = p.ProductCategory.Name, ListPrice = p.ListPrice, Color = p.Color, Description = p.ProductModel.ProductModelProductDescriptions. First().ProductDescription.Description }).FirstOrDefault(); if (produkt != null) { MultiView1.SetActiveView(prawidlowyView); Page.Title = "Przeglądasz: " + produkt.Name; nazwaLabel.Text = produkt.Name; produktImage.ImageUrl = "Miniatura.aspx?id=" + produkt.ProductID.ToString(); kategoriaLabel.Text = produkt.Category; cenaLabel.Text = String.Format("{0:C}", produkt.ListPrice); kolorLabel.Text = produkt.Color; opisLabel.Text = produkt.Description; } } Strona 9-8 Piotr Bubacz ITA-103 Aplikacje Internetowe 3. Zapisz i przetestuj dodaną funkcjonalnośd Moduł 9 LINQ w ASP.NET Zapisz zmiany w projekcie i przetestuj możliwośd wyświetlania produktów na stronie Szczegoly.aspx. Sprawdź co się stanie, jak w adresie przypiszesz do id inną wartośd, np. 1. Sprawdź co się stanie, jak w adresie przypiszesz do id ciąg znaków, np. a. Problem 3 (czas realizacji 10 min) Teraz musisz przygotowad kontrolkę wyświetlającą nowe produkty na szablonie strony . Zadanie Tok postępowania 1. Dodaj kontrolkę użytkownika wyświetlającą nowe produkty Do katalogu Kontrolki dodaj nową kontrolkę użytkownika o nazwie NoweProdukty.ascx. Następnie dodaj kontrolkę ListView i w oknie Properties: — w polu ID wpisz NoweProduktyListView — w polu ItemPlaceholderID wpisz ListaPlaceHolder W widoku Source w kontrolce ListView umieśd: <LayoutTemplate> <strong>Nasze nowe produkty:</strong><br /> <asp:PlaceHolder ID="ListaPlaceHolder" runat="server" /> </LayoutTemplate> <ItemTemplate> <div class="OknoProduktow" > <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# "~/Szczegoly.aspx?id="+Eval("ProductID") %>' Text='<%#Eval("Name") %>' /> <br /> <asp:Image ID="ProduktyImage" runat="server" ImageUrl='<%# "~/Miniatura.aspx?id=" + Eval("ProductID") %>' AlternateText='<%# Eval("Name") %>' /> <br /> Kategoria: <%#Eval("ProductCategory.Name") %> <br /> Kolor: <%#Eval("Color") %> <br /> Cena: <%#Eval("ListPrice", "{0:C}") %><br /> </div> </ItemTemplate> W metodzie Page_Load umieśd: AdventureWorksDataContext db = new AdventureWorksDataContext(); var noweProdukty = (from p in db.Products orderby p.SellStartDate descending select p).Take(4); NoweProduktyListView.DataSource = noweProdukty; NoweProduktyListView.DataBind(); Zapisz zmiany. 2. Dodaj kontrolkę do szablonu strony Otwórz szablon strony SzablonStrony.master. W widoku Design przenieś kontrolkę do obszaru roboczego położonego po prawej stronie o ID=DrugiObszarBoczny. Zapisz zmiany. 3. Dodaj kontrolkę do głównej strony aplikacji Otwórz stronę Default.aspx. W widoku Design przenieś kontrolkę do obszaru roboczego położonego w środku strony. Zapisz zmiany. Strona 9-9 Piotr Bubacz ITA-103 Aplikacje Internetowe Moduł 9 LINQ w ASP.NET 4. Zapis i przetestuj dodaną funkcjonalnośd Zapisz zmiany w projekcie i sprawdź, czy wyświetlane są nowe produkty w drugim obszarze roboczym na każdej stronie. 5. Ustal wygląd wyświetlanych produktów Do pliku Style.css dodaj następujące informacje o stylu: 6. Zapisz i przetestuj dodaną funkcjonalnośd Zapisz zmiany w projekcie i sprawdź, jak wyświetlane są nowe produkty w drugim obszarze roboczym na każdej stronie. .OknoProduktow { background-color: #C3DBEA; border-style: solid; border-color: #55BBFF; margin: 5px auto 0px auto; width: 120px; } Problem 4 (czas realizacji 10 min) Ostatnim zadaniem jest przygotowanie kontrolki wyświetlającej losowe produkty. Zadanie Tok postępowania 7. Dodaj widok i funkcję w TSQL umożliwiającą losowo wybieranie rekordów z bazy W oknie Server Explorer rozwio gałąź zawierającą plik AdventureWorksLT_Data.mdf i kliknij prawym przyciskiem myszy gałąź Views i wybierz Add New View. W oknie Add Table wciśnij przycisk Close. W oknie zapytania zastąp SELECT FROM następującym zapytaniem: SELECT NEWID() AS ID Wciśnij CTRL+S i wprowadź nazwę vLosuj. Kliknij prawym przyciskiem myszy gałąź Functions i wybierz Add New-> Scalar-valued Function. Zamieo zapytanie na: CREATE FUNCTION Losuj () RETURNS uniqueidentifier AS BEGIN RETURN (SELECT ID FROM vLosuj) END Wciśnij CTRL+S. 8. Dodanie W oknie Solution Explorer otwórz App_Code\AdventureWorks.dbml. funkcji Losuj do Do prawej strony opisanej Create methods by dragging items dodaj z obiektu okna Server Explorer funkcję Losuj z gałęzi Functions. AdventureWorksD ataContext 9. Dodaj kontrolkę użytkownika wyświetlającą nowe produkty Do katalogu Kontrolki dodaj nową kontrolkę użytkownika o nazwie WybraneProdukty.ascx. Następnie dodaj kontrolkę ListView i w oknie Properties: — w polu ID wpisz WybraneProduktyListView — w polu ItemPlaceholderID wpisz ListaPlaceHolder W widoku Source w kontrolce umieśd: <LayoutTemplate> <strong>Wybrane produkty:</strong> <asp:PlaceHolder ID="ListaPlaceHolder" runat="server" /> </LayoutTemplate> Strona 9-10 Piotr Bubacz ITA-103 Aplikacje Internetowe Moduł 9 LINQ w ASP.NET <ItemTemplate> <div class="OknoProduktow"> <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# "~/Szczegoly.aspx?id="+Eval("ProductID") %>' Text='<%#Eval("Name") %>' /> <br /> <asp:Image ID="ProduktyImage" runat="server" ImageUrl='<%# "~/Miniatura.aspx?id=" + Eval("ProductID") %>' AlternateText='<%# Eval("Name") %>' /> <br /> Kategoria: <%#Eval("ProductCategory.Name") %><br /> Kolor: <%#Eval("Color") %><br /> Cena: <%#Eval("ListPrice", "{0:C}") %><br /> </div> </ItemTemplate> W metodzie Page_Load umieśd: AdventureWorksDataContext db = new AdventureWorksDataContext(); var noweProdukty = (from p in db.Products orderby db.Losuj() select p).Take(3); WybraneProduktyListView.DataSource = noweProdukty; WybraneProduktyListView.DataBind(); Zapisz zmiany. 10. Dodaj kontrolkę do szablonu strony Otwórz szablon strony SzablonStrony.master. W widoku Design przenieś kontrolkę do obszaru roboczego położonego po lewej stronie o ID="PierwszyObszarBoczny". Zapisz zmiany. 11. Dodaj kontrolkę do głównej strony aplikacji Otwórz stronę Default.aspx W widoku Design usuo zawartośd strony i umieśd kontrolkę WybraneProdukty.ascx na stronę. Zapisz zmiany. 12. Zapis i przetestuj dodaną funkcjonalnośd Zapisz zmiany w projekcie i sprawdź czy wyświetlane są losowe produkty w pierwszym obszarze roboczym na każdej stronie. 13. Zapisz i przetestuj dodaną funkcjonalnośd Zapisz zmiany w projekcie i sprawdź jak wyświetlane są losowe produkty w pierwszym obszarze roboczym na każdej stronie. Strona 9-11