Sortowanie, filtrowanie i stronicowanie za pomocą programu Entity Framework w aplikacji MVC ASP.NET (3 z 10)

Autor : Tom Dykstra

Przykładowa aplikacja internetowa Contoso University pokazuje, jak utworzyć ASP.NET aplikacje MVC 4 przy użyciu platformy Entity Framework 5 Code First i programu Visual Studio 2012. Aby uzyskać informacje na temat serii samouczków, zobacz pierwszy samouczek z serii.

Uwaga

Jeśli napotkasz problem, którego nie możesz rozwiązać, pobierz ukończony rozdział i spróbuj odtworzyć problem. Zazwyczaj rozwiązanie problemu można znaleźć, porównując kod z ukończonym kodem. Niektóre typowe błędy i sposoby ich rozwiązywania można znaleźć w temacie Błędy i obejścia.

W poprzednim samouczku zaimplementowano zestaw stron internetowych dla podstawowych operacji CRUD dla jednostek Student . W tym samouczku dodasz funkcje sortowania, filtrowania i stronicowania do strony Indeks uczniów . Utworzysz również stronę, która wykonuje proste grupowanie.

Poniższa ilustracja przedstawia wygląd strony po zakończeniu. Nagłówki kolumn to linki, które użytkownik może kliknąć, aby posortować według tej kolumny. Klikanie nagłówka kolumny wielokrotnie przełącza się między kolejnością sortowania rosnącego i malejącego.

Students_Index_page_with_paging

Aby dodać sortowanie do strony Indeks uczniaStudent, zmienisz Index metodę kontrolera i dodasz kod do Student widoku Indeks.

Dodawanie funkcji sortowania do metody index

W pliku Controllers\StudentController.cs zastąp metodę Index następującym kodem:

public ActionResult Index(string sortOrder)
{
   ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name_desc" : "";
   ViewBag.DateSortParm = sortOrder == "Date" ? "Date_desc" : "Date";
   var students = from s in db.Students
                  select s;
   switch (sortOrder)
   {
      case "Name_desc":
         students = students.OrderByDescending(s => s.LastName);
         break;
      case "Date":
         students = students.OrderBy(s => s.EnrollmentDate);
         break;
      case "Date_desc":
         students = students.OrderByDescending(s => s.EnrollmentDate);
         break;
      default:
         students = students.OrderBy(s => s.LastName);
         break;
   }
   return View(students.ToList());
}

Ten kod odbiera sortOrder parametr z ciągu zapytania w adresie URL. Wartość ciągu zapytania jest dostarczana przez ASP.NET MVC jako parametr metody akcji. Parametr będzie ciągiem "Name" lub "Date", po którym opcjonalnie następuje podkreślenie i ciąg "desc", aby określić kolejność malejącą. Domyślna kolejność sortowania jest rosnąca.

Przy pierwszym żądaniu strony Indeks nie ma ciągu zapytania. Uczniowie są wyświetlani w kolejności rosnącej według LastName, która jest domyślnie określana przez przypadek upadek w instrukcji switch . Gdy użytkownik kliknie hiperlink nagłówka kolumny, w ciągu zapytania zostanie podana odpowiednia sortOrder wartość.

Te dwie ViewBag zmienne są używane, aby widok mógł skonfigurować hiperlinki nagłówka kolumny z odpowiednimi wartościami ciągu zapytania:

ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "Date_desc" : "Date";

Są toternarne instrukcje. Pierwszy określa, że jeśli sortOrder parametr ma wartość null lub jest pusty, ViewBag.NameSortParm powinien być ustawiony na wartość "name_desc"; w przeciwnym razie należy ustawić go na pusty ciąg. Te dwie instrukcje umożliwiają widokowi ustawianie hiperlinków nagłówków kolumn w następujący sposób:

Bieżąca kolejność sortowania Hiperłącze nazwiska Hiperłącze daty
Nazwisko rosnąco descending ascending
Nazwisko malejące ascending ascending
Data rosnąca ascending descending
Data malejąco ascending ascending

Metoda używa LINQ to Entities, aby określić kolumnę do sortowania. Kod tworzy zmienną IQueryable przed instrukcją switch , modyfikuje ją w switch instrukcji i wywołuje metodę ToList po instrukcji switch . Podczas tworzenia i modyfikowania IQueryable zmiennych żadne zapytanie nie jest wysyłane do bazy danych. Zapytanie nie jest wykonywane do momentu przekonwertowania IQueryable obiektu na kolekcję przez wywołanie metody takiej jak ToList. W związku z tym ten kod powoduje utworzenie pojedynczego zapytania, które nie jest wykonywane do momentu wykonania instrukcji return View .

W pliku Views\Student\Index.cshtml zastąp <tr> elementy i <th> dla wiersza nagłówka wyróżnionym kodem:

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm })
        </th>
        <th>First Name
        </th>
        <th>
            @Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm })
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
    {

Ten kod używa informacji we właściwościach ViewBag do konfigurowania hiperlinków z odpowiednimi wartościami ciągu zapytania.

Uruchom stronę i kliknij nagłówki kolumn Last Name (Nazwisko ) i Enrollment Date (Data rejestracji), aby sprawdzić, czy sortowanie działa.

Zrzut ekranu przedstawiający stronę indeksu studentów uniwersytetu Contoso. Nagłówki kolumn to Nazwisko, Imię i Data rejestracji.

Po kliknięciu nagłówka Last Name uczniowie są wyświetlani w kolejności malejącego nazwiska.

Zrzut ekranu przedstawiający stronę indeksu contoso University Students Index z listą studentów wyświetlaną w kolejności malejącej nazwiska.

Dodawanie pola wyszukiwania do strony indeksu uczniów

Aby dodać filtrowanie do strony Indeks uczniów, dodasz pole tekstowe i przycisk przesyłania do widoku i wprowadzisz odpowiednie zmiany w metodzie Index . Pole tekstowe umożliwi wprowadzenie ciągu do wyszukania w polach imienia i nazwiska.

Dodawanie funkcji filtrowania do metody index

W pliku Controllers\StudentController.cs zastąp metodę Index następującym kodem (zmiany są wyróżnione):

public ViewResult Index(string sortOrder, string searchString)
{
    ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
    ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
    var students = from s in db.Students
                   select s;
    if (!String.IsNullOrEmpty(searchString))
    {
        students = students.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
                               || s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
    }
    switch (sortOrder)
    {
        case "name_desc":
            students = students.OrderByDescending(s => s.LastName);
            break;
        case "Date":
            students = students.OrderBy(s => s.EnrollmentDate);
            break;
        case "date_desc":
            students = students.OrderByDescending(s => s.EnrollmentDate);
            break;
        default:
            students = students.OrderBy(s => s.LastName);
            break;
    }

    return View(students.ToList());
}

searchString Dodano parametr do Index metody . Dodano również do instrukcji LINQ klauzulę where , która wybiera tylko uczniów, których imię lub nazwisko zawiera ciąg wyszukiwania. Wartość ciągu wyszukiwania jest odbierana z pola tekstowego, które zostanie dodane do widoku Indeks. Instrukcja, która dodaje klauzulę where jest wykonywana tylko wtedy, gdy istnieje wartość do wyszukania.

Uwaga

W wielu przypadkach można wywołać tę samą metodę w zestawie jednostek programu Entity Framework lub jako metodę rozszerzenia w kolekcji w pamięci. Wyniki są zwykle takie same, ale w niektórych przypadkach mogą być różne. Na przykład implementacja Contains .NET Framework metody zwraca wszystkie wiersze po przekazaniu do niego pustego ciągu, ale dostawca programu Entity Framework dla SQL Server Compact 4.0 zwraca zero wierszy dla pustych ciągów. W związku z tym kod w przykładzie (umieszczenie Where instrukcji wewnątrz if instrukcji) zapewnia, że uzyskasz te same wyniki dla wszystkich wersji SQL Server. Ponadto implementacja .NET Framework Contains metody domyślnie wykonuje porównanie uwzględniające wielkość liter, ale dostawcy programu Entity Framework SQL Server domyślnie wykonują porównania bez uwzględniania wielkości liter. W związku z tym ToUpper wywołanie metody w celu jawnego bez uwzględniania wielkości liter w teście gwarantuje, że wyniki nie zmieniają się po zmianie kodu później w celu użycia repozytorium, co spowoduje zwrócenie IEnumerable kolekcji zamiast IQueryable obiektu. (Podczas wywoływania Contains metody IEnumerable w kolekcji uzyskujesz implementację .NET Framework. Podczas wywoływania jej w IQueryable obiekcie uzyskuje się implementację dostawcy bazy danych).

Dodawanie pola wyszukiwania do widoku indeksu ucznia

W pliku Views\Student\Index.cshtml dodaj wyróżniony kod bezpośrednio przed tagiem otwieraniatable, aby utworzyć podpis, pole tekstowe i przycisk Wyszukaj.

<p>
    @Html.ActionLink("Create New", "Create")
</p>

@using (Html.BeginForm())
{
    <p>
        Find by name: @Html.TextBox("SearchString")  
        <input type="submit" value="Search" /></p>
}

<table>
    <tr>

Uruchom stronę, wprowadź ciąg wyszukiwania, a następnie kliknij pozycję Wyszukaj , aby sprawdzić, czy filtrowanie działa.

Students_Index_page_with_search_box

Zwróć uwagę, że adres URL nie zawiera ciągu wyszukiwania "an", co oznacza, że jeśli oznaczysz tę stronę zakładką, nie otrzymasz filtrowanej listy podczas korzystania z zakładki. W dalszej części samouczka zmienisz przycisk Wyszukaj , aby użyć ciągów zapytania dla kryteriów filtrowania.

Dodawanie stronicowania do strony indeksu uczniów

Aby dodać stronicowanie do strony Indeks uczniów, zacznij od zainstalowania pakietu NuGet PagedList.Mvc . Następnie wprowadzisz dodatkowe zmiany w metodzie Index i dodasz linki stronicowania do Index widoku. PagedList.Mvc jest jednym z wielu dobrych pakietów stronicowania i sortowania dla ASP.NET MVC, a jego użycie jest przeznaczone tylko jako przykład, a nie jako zalecenie dla niego w przypadku innych opcji. Poniższa ilustracja przedstawia łącza stronicowania.

Zrzut ekranu przedstawiający stronę Indeks uczniów z linkami stronicowania.

Instalowanie pakietu NuGet PagedList.MVC

Pakiet NuGet PagedList.Mvc automatycznie instaluje pakiet PagedList jako zależność. Pakiet PagedList instaluje PagedList metody typu kolekcji i rozszerzenia dla IQueryable kolekcji i IEnumerable . Metody rozszerzenia tworzą jedną stronę danych w kolekcji poza twoją kolekcją PagedList lub IEnumerable, a PagedList kolekcja udostępnia kilka właściwości i metod, które ułatwiają IQueryable stronicowanie. Pakiet PagedList.Mvc instaluje pomocnika stronicowania, który wyświetla przyciski stronicowania.

W menu Narzędzia wybierz pozycję Menedżer pakietów NuGet , a następnie pozycję Zarządzaj pakietami NuGet dla rozwiązania.

W oknie dialogowym Zarządzanie pakietami NuGet kliknij kartę Online po lewej stronie, a następnie wprowadź ciąg "paged" w polu wyszukiwania. Po wyświetleniu pakietu PagedList.Mvc kliknij przycisk Zainstaluj.

Zrzut ekranu przedstawiający okno dialogowe Zarządzanie N u GET Packages. Karta Online i pasek wyszukiwania wypełniony wyrazem stronicowanym są wyróżnione. Wybrano pakiet Lista stronicowana.

W polu Wybierz projekty kliknij przycisk OK.

Zrzut ekranu przedstawiający okno dialogowe Wybieranie projektu. Przycisk O K jest zaznaczony.

Dodawanie funkcji stronicowania do metody index

W pliku Controllers\StudentController.cs dodaj instrukcję using dla PagedList przestrzeni nazw:

using PagedList;

Zastąp metodę Index poniższym kodem:

public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
   ViewBag.CurrentSort = sortOrder;
   ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
   ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";

   if (searchString != null)
   {
      page = 1;
   }
   else
   {
      searchString = currentFilter;
   }

   ViewBag.CurrentFilter = searchString;

   var students = from s in db.Students
                  select s;
   if (!String.IsNullOrEmpty(searchString))
   {
      students = students.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
                             || s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
   }
   switch (sortOrder)
   {
      case "name_desc":
         students = students.OrderByDescending(s => s.LastName);
         break;
      case "Date":
         students = students.OrderBy(s => s.EnrollmentDate);
         break;
      case "date_desc":
         students = students.OrderByDescending(s => s.EnrollmentDate);
         break;
      default:  // Name ascending 
         students = students.OrderBy(s => s.LastName);
         break;
   }

   int pageSize = 3;
   int pageNumber = (page ?? 1);
   return View(students.ToPagedList(pageNumber, pageSize));
}

Ten kod dodaje page parametr, bieżący parametr kolejności sortowania i bieżący parametr filtru do podpisu metody, jak pokazano poniżej:

public ActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)

Przy pierwszym wyświetleniu strony lub jeśli użytkownik nie kliknął łącza stronicowania lub sortowania, wszystkie parametry będą mieć wartość null. Jeśli klikniesz link stronicowania, zmienna page będzie zawierać numer strony do wyświetlenia.

A ViewBag właściwość udostępnia widok z bieżącą kolejnością sortowania, ponieważ musi ona być uwzględniona w linkach stronicowania, aby zachować kolejność sortowania tak samo podczas stronicowania:

ViewBag.CurrentSort = sortOrder;

Inna właściwość , ViewBag.CurrentFilterudostępnia widok z bieżącym ciągiem filtru. Ta wartość musi być uwzględniona w linkach stronicowania, aby zachować ustawienia filtru podczas stronicowania i należy ją przywrócić do pola tekstowego, gdy strona zostanie ponownie odtworzona. Jeśli ciąg wyszukiwania zostanie zmieniony podczas stronicowania, strona musi zostać zresetowana do wartości 1, ponieważ nowy filtr może spowodować wyświetlenie różnych danych. Ciąg wyszukiwania jest zmieniany po wprowadzeniu wartości w polu tekstowym i naciśnięciu przycisku przesyłania. W takim przypadku searchString parametr nie ma wartości null.

if (searchString != null)
        page = 1;
else
    searchString = currentFilter;

Na końcu metody ToPagedList metoda rozszerzenia obiektu students IQueryable konwertuje zapytanie ucznia na jedną stronę uczniów w typie kolekcji, który obsługuje stronicowanie. Ta pojedyncza strona uczniów jest następnie przekazywana do widoku:

int pageSize = 3;
int pageNumber = (page ?? 1);
return View(students.ToPagedList(pageNumber, pageSize));

Metoda ToPagedList przyjmuje numer strony. Dwa znaki zapytania reprezentują operator łączenia wartości null. Operator łączenia wartości null definiuje wartość domyślną dla typu dopuszczającego wartość null; wyrażenie (page ?? 1) oznacza, że zwraca wartość page , jeśli ma wartość, lub zwraca wartość 1, jeśli page ma wartość null.

W pliku Views\Student\Index.cshtml zastąp istniejący kod następującym kodem:

@model PagedList.IPagedList<ContosoUniversity.Models.Student>
@using PagedList.Mvc; 
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />

@{
    ViewBag.Title = "Students";
}

<h2>Students</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
@using (Html.BeginForm("Index", "Student", FormMethod.Get))
{
    <p>
        Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)  
        <input type="submit" value="Search" />
    </p>
}
<table>
<tr>
    <th></th>
    <th>
        @Html.ActionLink("Last Name", "Index", new { sortOrder=ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })
    </th>
    <th>
        First Name
    </th>
    <th>
        @Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter = ViewBag.CurrentFilter })
    </th>
</tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.StudentID }) |
            @Html.ActionLink("Details", "Details", new { id=item.StudentID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.StudentID })
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.LastName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.FirstMidName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.EnrollmentDate)
        </td>
    </tr>
}

</table>
<br />
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount

@Html.PagedListPager( Model, page => Url.Action("Index", new { page, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter }) )

Instrukcja @model w górnej części strony określa, że widok pobiera PagedList teraz obiekt zamiast List obiektu.

Instrukcja using dla PagedList.Mvc elementu zapewnia dostęp do pomocnika MVC dla przycisków stronicowania.

Kod używa przeciążenia elementu BeginForm , które umożliwia określenie metody FormMethod.Get.

@using (Html.BeginForm("Index", "Student", FormMethod.Get))
{
    <p>
        Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)  
        <input type="submit" value="Search" />
    </p>
}

Domyślny formularz BeginForm przesyła dane formularza za pomocą funkcji POST, co oznacza, że parametry są przekazywane w treści komunikatu HTTP, a nie w adresie URL jako ciągi zapytania. Po określeniu żądania HTTP GET dane formularza są przekazywane w adresie URL jako ciągi zapytania, co umożliwia użytkownikom dodawanie zakładek adresu URL. Wytyczne W3C dotyczące korzystania z żądania HTTP GET określają, że należy użyć polecenia GET, gdy akcja nie spowoduje aktualizacji.

Pole tekstowe jest inicjowane przy użyciu bieżącego ciągu wyszukiwania, więc po kliknięciu nowej strony można zobaczyć bieżący ciąg wyszukiwania.

Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)

Linki nagłówka kolumny używają ciągu zapytania, aby przekazać bieżący ciąg wyszukiwania do kontrolera, aby użytkownik mógł sortować wyniki filtru:

@Html.ActionLink("Last Name", "Index", new { sortOrder=ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })

Wyświetlana jest bieżąca strona i łączna liczba stron.

Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount

Jeśli nie ma stron do wyświetlenia, zostanie wyświetlona wartość "Strona 0 z 0". (W takim przypadku numer strony jest większy niż liczba stron, ponieważ Model.PageNumber wynosi 1 i Model.PageCount wynosi 0).

Przyciski stronicowania są wyświetlane przez PagedListPager pomocnika:

@Html.PagedListPager( Model, page => Url.Action("Index", new { page }) )

Pomocnik PagedListPager udostępnia szereg opcji, które można dostosować, w tym adresy URL i style. Aby uzyskać więcej informacji, zobacz TroyGoode / PagedList w witrynie GitHub.

Uruchom stronę.

Zrzut ekranu przedstawiający stronę Indeks uczniów.

Kliknij łącza stronicowania w różnych kolejności sortowania, aby upewnić się, że stronicowanie działa. Następnie wprowadź ciąg wyszukiwania i spróbuj ponownie stronicować, aby sprawdzić, czy stronicowanie działa również poprawnie z sortowaniem i filtrowaniem.

Zrzut ekranu przedstawiający stronę Indeks uczniów. Wyraz an jest wprowadzany na pasku wyszukiwania Znajdź według nazw.

Tworzenie strony About (Informacje) przedstawiającej statystyki uczniów

Na stronie Informacje o witrynie internetowej Contoso University zobaczysz, ilu studentów zarejestrowało się dla każdej daty rejestracji. Wymaga to grupowania i prostych obliczeń w grupach. W tym celu należy wykonać następujące czynności:

  • Utwórz klasę modelu widoku dla danych, które należy przekazać do widoku.
  • Zmodyfikuj metodę About w kontrolerze Home .
  • Zmodyfikuj About widok.

Tworzenie modelu widoku

Utwórz folder ViewModels . W tym folderze dodaj plik klasy EnrollmentDateGroup.cs i zastąp istniejący kod następującym kodem:

using System;
using System.ComponentModel.DataAnnotations;

namespace ContosoUniversity.ViewModels
{
    public class EnrollmentDateGroup
    {
        [DataType(DataType.Date)]
        public DateTime? EnrollmentDate { get; set; }

        public int StudentCount { get; set; }
    }
}

Modyfikowanie kontrolera głównego

W pliku HomeController.cs dodaj następujące using instrukcje w górnej części pliku:

using ContosoUniversity.DAL;
using ContosoUniversity.ViewModels;

Dodaj zmienną klasy dla kontekstu bazy danych natychmiast po otwarciu nawiasu klamrowego dla klasy:

public class HomeController : Controller
{
    private SchoolContext db = new SchoolContext();

Zastąp metodę About poniższym kodem:

public ActionResult About()
{
    var data = from student in db.Students
               group student by student.EnrollmentDate into dateGroup
               select new EnrollmentDateGroup()
               {
                   EnrollmentDate = dateGroup.Key,
                   StudentCount = dateGroup.Count()
               };
    return View(data);
}

Instrukcja LINQ grupuje jednostki uczniów według daty rejestracji, oblicza liczbę jednostek w każdej grupie i przechowuje wyniki w kolekcji EnrollmentDateGroup obiektów modelu widoku.

Dodaj metodę Dispose :

protected override void Dispose(bool disposing)
{
    db.Dispose();
    base.Dispose(disposing);
}

Modyfikowanie widoku Informacje

Zastąp kod w pliku Views\Home\About.cshtml następującym kodem:

@model IEnumerable<ContosoUniversity.ViewModels.EnrollmentDateGroup>
           
@{
    ViewBag.Title = "Student Body Statistics";
}

<h2>Student Body Statistics</h2>

<table>
    <tr>
        <th>
            Enrollment Date
        </th>
        <th>
            Students
        </th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.EnrollmentDate)
        </td>
        <td>
            @item.StudentCount
        </td>
    </tr>
}
</table>

Uruchom aplikację i kliknij link Informacje . Liczba uczniów dla każdej daty rejestracji jest wyświetlana w tabeli.

About_page

Opcjonalnie: wdrażanie aplikacji na platformie Windows Azure

Do tej pory aplikacja była uruchomiona lokalnie w IIS Express na komputerze dewelopera. Aby udostępnić go innym osobom do użycia przez Internet, należy wdrożyć go u dostawcy hostingu internetowego. W tej opcjonalnej sekcji samouczka wdrożysz ją w witrynie internetowej platformy Windows Azure.

Wdrażanie bazy danych przy użyciu Migracje Code First

Aby wdrożyć bazę danych, użyjesz Migracje Code First. Podczas tworzenia profilu publikowania używanego do konfigurowania ustawień wdrażania z poziomu programu Visual Studio zaznacz pole wyboru z etykietą Wykonaj Migracje Code First (uruchamiane przy uruchomieniu aplikacji). To ustawienie powoduje, że proces wdrażania automatycznie konfiguruje plik Web.config aplikacji na serwerze docelowym, tak aby program Code First używał klasy inicjatora MigrateDatabaseToLatestVersion .

Program Visual Studio nie wykonuje żadnych czynności z bazą danych podczas procesu wdrażania. Gdy wdrożona aplikacja uzyskuje dostęp do bazy danych po raz pierwszy po wdrożeniu, program Code First automatycznie tworzy bazę danych lub aktualizuje schemat bazy danych do najnowszej wersji. Jeśli aplikacja implementuje metodę Migrations Seed , metoda jest uruchamiana po utworzeniu bazy danych lub zaktualizowaniu schematu.

Metoda Migrations Seed wstawia dane testowe. W przypadku wdrażania w środowisku produkcyjnym należy zmienić Seed metodę tak, aby wstawiała tylko dane, które mają zostać wstawione do produkcyjnej bazy danych. Na przykład w bieżącym modelu danych możesz chcieć mieć prawdziwe kursy, ale fikcyjnych studentów w bazie danych programowania. Możesz napisać metodę Seed ładowania zarówno w środowisku deweloperskim, jak i skomentować fikcyjnych uczniów przed wdrożeniem w środowisku produkcyjnym. Możesz też napisać metodę Seed ładowania tylko kursów i ręcznie wprowadzić fikcyjnych uczniów w testowej bazie danych przy użyciu interfejsu użytkownika aplikacji.

Uzyskiwanie konta platformy Windows Azure

Będziesz potrzebować konta platformy Windows Azure. Jeśli jeszcze go nie masz, możesz utworzyć bezpłatne konto próbne w ciągu zaledwie kilku minut. Aby uzyskać szczegółowe informacje, zobacz Bezpłatna wersja próbna platformy Microsoft Azure.

Tworzenie witryny internetowej i bazy danych SQL na platformie Windows Azure

Witryna sieci Web platformy Windows Azure zostanie uruchomiona w udostępnionym środowisku hostingu, co oznacza, że działa na maszynach wirtualnych, które są współużytkowane z innymi klientami platformy Microsoft Azure. Współużytkowane środowisko hostingu to ekonomiczny sposób rozpoczęcia pracy w chmurze. Później, jeśli ruch internetowy wzrośnie, aplikacja może być skalowana w celu zaspokojenia potrzeb, uruchamiając na dedykowanych maszynach wirtualnych. Jeśli potrzebujesz bardziej złożonej architektury, możesz przeprowadzić migrację do usługi w chmurze platformy Windows Azure. Usługi w chmurze działają na dedykowanych maszynach wirtualnych, które można skonfigurować zgodnie z potrzebami.

Windows Azure SQL Database to oparta na chmurze usługa relacyjnej bazy danych oparta na technologiach SQL Server. Narzędzia i aplikacje współpracujące z SQL Server również współdziałają z SQL Database.

  1. W portalu zarządzania platformy Windows Azure kliknij pozycję Witryny internetowe na lewej karcie, a następnie kliknij pozycję Nowy.

    Przycisk Nowy w portalu zarządzania

  2. Kliknij pozycję UTWÓRZ NIESTANDARDOWE.

    Zrzut ekranu przedstawiający okno dialogowe Nowy. Opcje witryny sieci Web i tworzenia niestandardowego są wyróżnione.

    Zostanie otwarty kreator Nowa witryna sieci Web — tworzenie niestandardowe .

  3. W kroku Kreatora Nowa witryna sieci Web wprowadź ciąg w polu Adres URL , który ma być używany jako unikatowy adres URL aplikacji. Pełny adres URL będzie składał się z wprowadzonego tutaj znaku plus sufiksu widocznego obok pola tekstowego. Ilustracja przedstawia ciąg "ConU", ale ten adres URL prawdopodobnie jest pobierany, więc trzeba będzie wybrać inny.

    Tworzenie za pomocą linku bazy danych w portalu zarządzania

  4. Z listy rozwijanej Region wybierz region znajdujący się blisko Ciebie. To ustawienie określa, w którym centrum danych będzie działać witryna sieci Web.

  5. Z listy rozwijanej Baza danych wybierz pozycję Utwórz bezpłatną bazę danych SQL o wartości 20 MB.

    Zrzut ekranu przedstawiający okno dialogowe Tworzenie witryny sieci Web. Z listy rozwijanej bazy danych wybierz bezpłatną bazę danych 20 M B S Q L. Przycisk znacznika wyboru jest wyróżniony.

  6. W polu NAZWA PARAMETRÓW POŁĄCZENIA BAZY DANYCH wprowadź wartość SchoolContext.

    Zrzut ekranu przedstawiający okno dialogowe Tworzenie witryny sieci Web. Kontekst szkoły jest wypełniany w polu tekstowym Nazwa parametrów połączenia D B. Przycisk znacznika wyboru jest wyróżniony.

  7. Kliknij strzałkę wskazującą prawą część w dolnej części pola. Kreator przechodzi do kroku Ustawienia bazy danych .

  8. W polu Nazwa wprowadź wartość ContosoUniversityDB.

  9. W polu Serwer wybierz pozycję Nowy serwer SQL Database. Alternatywnie, jeśli wcześniej utworzono serwer, możesz wybrać ten serwer z listy rozwijanej.

  10. Wprowadź nazwę LOGOWANIA administratora i hasło. W przypadku wybrania opcji Nowy serwer usługi SQL Database w tym miejscu nie wprowadzasz istniejącej nazwy i hasła — podajesz nową nazwę i hasło definiowane w tej chwili do użycia w przyszłości podczas uzyskiwania dostępu do bazy danych. W przypadku wybrania utworzonego wcześniej serwera wprowadź poświadczenia dla tego serwera. Na potrzeby tego samouczka nie zaznaczysz pola wyboru Zaawansowane . Opcje zaawansowane umożliwiają ustawienie sortowania bazy danych.

  11. Wybierz ten sam region , który został wybrany dla witryny sieci Web.

  12. Kliknij znacznik wyboru w prawym dolnym rogu pola, aby wskazać, że skończysz.

    Zrzut ekranu przedstawiający okno dialogowe Określanie ustawień bazy danych z wybranymi wszystkimi ustawieniami i przykładowym hasłem zawartym w polach tekstowych. Przycisk znacznika wyboru jest wyróżniony.

    Na poniższej ilustracji przedstawiono użycie istniejących SQL Server i identyfikatorów logowania.

    Krok Ustawienia bazy danych nowej witryny sieci Web — kreator tworzenia za pomocą bazy danych

    Portal zarządzania powróci do strony Witryny sieci Web, a kolumna Stan pokazuje, że witryna jest tworzona. Po chwili (zazwyczaj krócej niż minutę) w kolumnie Stan zostanie wyświetlona informacja o pomyślnym utworzeniu witryny. Na pasku nawigacyjnym po lewej stronie liczba witryn znajdujących się na twoim koncie jest wyświetlana obok ikony Witryny sieci Web , a liczba baz danych jest wyświetlana obok ikony Bazy danych SQL .

Wdrażanie aplikacji na platformie Windows Azure

  1. W programie Visual Studio kliknij prawym przyciskiem myszy projekt w Eksplorator rozwiązań i wybierz polecenie Publikuj z menu kontekstowego.

    Menu kontekstowe Publikowanie w projekcie

  2. Na karcie Profil kreatora Publikowanie w sieci Web kliknij pozycję Importuj.

    Importowanie ustawień publikowania

  3. Jeśli subskrypcja platformy Microsoft Azure nie jest wcześniej dodana w programie Visual Studio, wykonaj następujące kroki. W tych krokach dodasz subskrypcję, aby lista rozwijana w obszarze Importuj z witryny internetowej platformy Windows Azure zawierała witrynę internetową.

    a. W oknie dialogowym Importowanie profilu publikowania kliknij pozycję Importuj z witryny internetowej platformy Windows Azure, a następnie kliknij pozycję Dodaj subskrypcję platformy Windows Azure.

    dodawanie subskrypcji platformy Windows Azure

    b. W oknie dialogowym Importowanie subskrypcji platformy Windows Azure kliknij pozycję Pobierz plik subskrypcji.

    pobieranie pliku subskrypcji

    c. W oknie przeglądarki zapisz plik publishsettings .

    pobierz plik publishsettings

    Ostrzeżenie

    Zabezpieczenia — plik publishsettings zawiera poświadczenia (niezakodowane), które są używane do administrowania subskrypcjami i usługami platformy Microsoft Azure. Najlepszym rozwiązaniem w zakresie zabezpieczeń dla tego pliku jest tymczasowe przechowywanie go poza katalogami źródłowymi (na przykład w folderze Libraries\Documents ), a następnie usunięcie go po zakończeniu importowania. Złośliwy użytkownik, który uzyskuje dostęp do .publishsettings pliku, może edytować, tworzyć i usuwać usługi platformy Windows Azure.

    d. W oknie dialogowym Importowanie subskrypcji platformy Windows Azure kliknij przycisk Przeglądaj i przejdź do pliku publishsettings .

    pobierz podzbię

    e. Kliknij przycisk Importuj.

    Importu

  4. W oknie dialogowym Importowanie profilu publikowania wybierz pozycję Importuj z witryny internetowej platformy Windows Azure, wybierz witrynę internetową z listy rozwijanej, a następnie kliknij przycisk OK.

    Importowanie profilu publikowania

  5. Na karcie Połączenie kliknij pozycję Zweryfikuj połączenie , aby upewnić się, że ustawienia są poprawne.

    Weryfikowanie połączenia

  6. Po zweryfikowaniu połączenia obok przycisku Weryfikuj połączenie jest wyświetlany zielony znacznik wyboru. Kliknij przycisk Dalej.

    Pomyślnie zweryfikowano połączenie

  7. Otwórz listę rozwijaną Parametry połączenia zdalnego w obszarze SchoolContext i wybierz parametry połączenia dla utworzonej bazy danych.

  8. Wybierz pozycję Wykonaj Migracje Code First (uruchamiane przy uruchomieniu aplikacji).

  9. Usuń zaznaczenie pola wyboru Użyj tych parametrów połączenia w czasie wykonywania dla elementu UserContext (DefaultConnection), ponieważ ta aplikacja nie używa bazy danych członkostwa.

    Karta Ustawienia

  10. Kliknij przycisk Dalej.

  11. Na karcie Podgląd kliknij pozycję Rozpocznij podgląd.

    Przycisk StartPrzegląd na karcie Podgląd

    Karta zawiera listę plików, które zostaną skopiowane na serwer. Wyświetlanie podglądu nie jest wymagane do opublikowania aplikacji, ale jest przydatną funkcją, o których należy pamiętać. W takim przypadku nie trzeba wykonywać żadnych czynności z listą wyświetlanych plików. Przy następnym wdrożeniu tej aplikacji na tej liście będą znajdować się tylko zmienione pliki.

    Dane wyjściowe pliku StartPreview

  12. Kliknij przycisk Opublikuj.
    Program Visual Studio rozpoczyna proces kopiowania plików na serwer platformy Windows Azure.

  13. W oknie Dane wyjściowe pokazano, jakie akcje wdrożenia zostały wykonane, a następnie raportuje pomyślne ukończenie wdrożenia.

    Okno danych wyjściowych zgłasza pomyślne wdrożenie

  14. Po pomyślnym wdrożeniu domyślna przeglądarka automatycznie otwiera adres URL wdrożonej witryny internetowej.
    Utworzona aplikacja jest teraz uruchomiona w chmurze. Kliknij kartę Uczniowie.

    Students_index_page_with_paging

Na tym etapie baza danych SchoolContext została utworzona w bazie danych systemu Windows Azure SQL, ponieważ wybrano pozycję Wykonaj Migracje Code First (działa przy uruchomieniu aplikacji). Plik Web.config w wdrożonej witrynie sieci Web został zmieniony tak, aby inicjator MigrateDatabaseToLatestVersion uruchamiał pierwszy raz, gdy kod odczytuje lub zapisuje dane w bazie danych (co miało miejsce po wybraniu karty Uczniowie ):

Zrzut ekranu przedstawiający kod z wyróżnioną wyróżnioną migracją bazy danych do najnowszej wersji.

Proces wdrażania utworzył również nowe parametry połączenia (SchoolContext_DatabasePublish) dla Migracje Code First do użycia do aktualizowania schematu bazy danych i rozmieszczania bazy danych.

Database_Publish parametry połączenia

Parametry połączenia DefaultConnection dotyczą bazy danych członkostwa (której nie używamy w tym samouczku). Parametry połączenia SchoolContext są przeznaczone dla bazy danych ContosoUniversity.

Wdrożoną wersję pliku Web.config można znaleźć na własnym komputerze w ContosoUniversity\obj\Release\Package\PackageTmp\Web.config. Dostęp do wdrożonego pliku Web.config można uzyskać za pomocą protokołu FTP. Aby uzyskać instrukcje, zobacz ASP.NET Web Deployment using Visual Studio: Deploying a Code Update (Wdrażanie aktualizacji kodu przy użyciu programu Visual Studio: wdrażanie aktualizacji kodu). Postępuj zgodnie z instrukcjami rozpoczynającymi się od ciągu "Aby użyć narzędzia FTP, potrzebne są trzy elementy: adres URL FTP, nazwa użytkownika i hasło".

Uwaga

Aplikacja internetowa nie implementuje zabezpieczeń, więc każdy, kto znajdzie adres URL, może zmienić dane. Aby uzyskać instrukcje dotyczące zabezpieczania witryny internetowej, zobacz Deploy a Secure ASP.NET MVC app with Membership, OAuth, and SQL Database to a Windows Azure Web Site (Wdrażanie bezpiecznej aplikacji MVC przy użyciu członkostwa, uwierzytelniania OAuth i SQL Database w witrynie internetowej platformy Windows Azure). Możesz uniemożliwić innym osobom korzystanie z witryny za pomocą portalu zarządzania Platformy Windows Azure lub Eksploratora serwera w programie Visual Studio, aby zatrzymać witrynę.

Zrzut ekranu Przedstawiający Eksploratora serwera z rozwiniętą kartą Witryna internetowa platformy Windows Azure i poniżej wybranego narzędzia Con U. Wyróżniono menu dialogowe z opcją Zatrzymaj witrynę sieci Web.

Inicjatory Code First

W sekcji wdrażania zobaczyliśmy używany inicjator MigrateDatabaseToLatestVersion . Code First udostępnia również inne inicjatory, których można użyć, w tym CreateDatabaseIfNotExists (ustawienie domyślne), DropCreateDatabaseIfModelChanges i DropCreateDatabaseAlways. Inicjator DropCreateAlways może być przydatny do konfigurowania warunków testów jednostkowych. Możesz również napisać własne inicjatory i wywołać inicjator jawnie, jeśli nie chcesz czekać, aż aplikacja odczytuje lub zapisuje w bazie danych. Aby uzyskać kompleksowe wyjaśnienie inicjatorów, zobacz rozdział 6 książki Programming Entity Framework: Code First autorstwa Julie Lerman i Rowan Miller.

Podsumowanie

W tym samouczku pokazano, jak utworzyć model danych i zaimplementować podstawową funkcję CRUD, sortowanie, filtrowanie, stronicowanie i grupowanie. W następnym samouczku zaczniesz przyglądać się bardziej zaawansowanym tematom, rozszerzając model danych.

Linki do innych zasobów programu Entity Framework można znaleźć na mapie zawartości dostępu do danych ASP.NET.