ITA-103 Aplikacje Internetowe
Piotr Bubacz
Moduł 9
Wersja 1
LINQ w ASP.NET
Spis treści
Piotr Bubacz
Moduł 9
ITA-103 Aplikacje Internetowe
LINQ w ASP.NET
Strona 9-2
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Ł 9
MODUŁ 14
MODUŁ 3
MODUŁ 6
MODUŁ 1
MODUŁ 5
MODUŁ 2
MODUŁ 4
MODUŁ 8
MODUŁ 10
MODUŁ 11
MODUŁ 12
MODUŁ 13
Rys. 1 Mapa zależności modułu
Piotr Bubacz
Moduł 9
ITA-103 Aplikacje Internetowe
LINQ w ASP.NET
Strona 9-3
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.
<book>
<title/>
<author/>
<year/>
<price/>
</book>
.NET Language Integrated Query
Rys. 2 Architektura i komponenty LINQ
Piotr Bubacz
Moduł 9
ITA-103 Aplikacje Internetowe
LINQ w ASP.NET
Strona 9-4
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
Piotr Bubacz
Moduł 9
ITA-103 Aplikacje Internetowe
LINQ w ASP.NET
Strona 9-5
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.
Piotr Bubacz
Moduł 9
ITA-103 Aplikacje Internetowe
LINQ w ASP.NET
Strona 9-6
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.
Piotr Bubacz
Moduł 9
ITA-103 Aplikacje Internetowe
LINQ w ASP.NET
Strona 9-7
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:
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());
}
}
3. Zapis i
przetestuj dodaną
funkcjonalnośd
Zapisz zmiany w projekcie. Wyświetl stronę Miniatura.aspx i sprawdź,
co jest wyświetlane.
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:
— w polu DataAlternateTextField wpisz Name
— w polu DataAlternateTextFormatString wpisz Miniatura {0}
— w polu DataImageUrlField wpisz ProductID
— w polu DataImageUrlFormatString wpisz ~/Miniatura.aspx?id={0}
5. Zapisz i
przetestuj dodaną
funkcjonalnośd
Zapisz zmiany w projekcie. Wyświetl stronę Produkty.aspx i sprawdź,
czy wyświetlane są miniatury produktów.
Piotr Bubacz
Moduł 9
ITA-103 Aplikacje Internetowe
LINQ w ASP.NET
Strona 9-8
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;
} }
Piotr Bubacz
Moduł 9
ITA-103 Aplikacje Internetowe
LINQ w ASP.NET
Strona 9-9
3. Zapisz i
przetestuj dodaną
funkcjonalnośd
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.
Piotr Bubacz
Moduł 9
ITA-103 Aplikacje Internetowe
LINQ w ASP.NET
Strona 9-10
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:
.OknoProduktow
{
background-color: #C3DBEA;
border-style: solid;
border-color: #55BBFF;
margin: 5px auto 0px auto;
width: 120px;
}
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.
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
funkcji Losuj do
obiektu
AdventureWorksD
ataContext
W oknie Solution Explorer otwórz App_Code\AdventureWorks.dbml.
Do prawej strony opisanej Create methods by dragging items dodaj z
okna Server Explorer funkcję Losuj z gałęzi Functions.
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>
Piotr Bubacz
Moduł 9
ITA-103 Aplikacje Internetowe
LINQ w ASP.NET
Strona 9-11
<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.