Esercitazione: aggiungere ordinamento, filtro e paging con la Entity Framework in un'applicazione MVC ASP.NETTutorial: Add sorting, filtering, and paging with the Entity Framework in an ASP.NET MVC application

Nell' esercitazione precedenteè stato implementato un set di pagine Web per le operazioni CRUD di base per le entità Student.In the previous tutorial, you implemented a set of web pages for basic CRUD operations for Student entities. In questa esercitazione si aggiungono funzionalità di ordinamento, filtro e paging alla pagina di indice students .In this tutorial you add sorting, filtering, and paging functionality to the Students Index page. Viene inoltre creata una semplice pagina di raggruppamento.You also create a simple grouping page.

La figura seguente mostra l'aspetto della pagina al termine dell'operazione.The following image shows what the page will look like when you're done. Le intestazioni di colonna sono collegamenti su cui l'utente può fare clic per eseguire l'ordinamento in base alla colonna.The column headings are links that the user can click to sort by that column. Facendo clic più volte su un'intestazione di colonna è possibile passare dall'ordinamento crescente a quello decrescente e viceversa.Clicking a column heading repeatedly toggles between ascending and descending sort order.

Students_Index_page_with_paging

Le attività di questa esercitazione sono le seguenti:In this tutorial, you:

  • Aggiungere collegamenti per l'ordinamento delle colonneAdd column sort links
  • Aggiungere una casella di ricercaAdd a Search box
  • Aggiungere la suddivisione in pagineAdd paging
  • Creare una pagina AboutCreate an About page

PrerequisitiPrerequisites

Per aggiungere l'ordinamento alla pagina Student index, è necessario modificare il metodo Index del controller di Student e aggiungere il codice alla vista Student index.To add sorting to the Student Index page, you'll change the Index method of the Student controller and add code to the Student Index view.

Aggiungere la funzionalità di ordinamento al metodo indexAdd sorting functionality to the Index method

  • In Controllers\StudentController.cssostituire il metodo Index con il codice seguente:In Controllers\StudentController.cs, replace the Index method with the following code:

    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());
    }
    

Questo codice riceve un parametro sortOrder dalla stringa di query nell'URL.This code receives a sortOrder parameter from the query string in the URL. Il valore della stringa di query viene fornito da ASP.NET MVC come parametro al metodo di azione.The query string value is provided by ASP.NET MVC as a parameter to the action method. Il parametro è una stringa "Name" o "date", facoltativamente seguita da un carattere di sottolineatura e dalla stringa "DESC" per specificare l'ordine decrescente.The parameter is a string that's either "Name" or "Date", optionally followed by an underscore and the string "desc" to specify descending order. L'ordinamento predefinito è crescente.The default sort order is ascending.

La prima volta che viene richiesta la pagina di indice, non è presente alcuna stringa di query.The first time the Index page is requested, there's no query string. Gli studenti vengono visualizzati in ordine crescente per LastName, che è l'impostazione predefinita stabilita dal caso di rientri nell'istruzione switch.The students are displayed in ascending order by LastName, which is the default as established by the fall-through case in the switch statement. Quando l'utente fa clic sul collegamento ipertestuale di un'intestazione di colonna, nella stringa di query viene specificato il valore sortOrder appropriato.When the user clicks a column heading hyperlink, the appropriate sortOrder value is provided in the query string.

Vengono usate le due variabili ViewBag in modo che la visualizzazione possa configurare i collegamenti ipertestuali dell'intestazione di colonna con i valori della stringa di query appropriati:The two ViewBag variables are used so that the view can configure the column heading hyperlinks with the appropriate query string values:

ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";

Si tratta di istruzioni ternarie.These are ternary statements. Il primo specifica che se il parametro sortOrder è null o vuoto, ViewBag.NameSortParm deve essere impostato su "nome_DESC"; in caso contrario, deve essere impostato su una stringa vuota.The first one specifies that if the sortOrder parameter is null or empty, ViewBag.NameSortParm should be set to "name_desc"; otherwise, it should be set to an empty string. Queste due istruzioni consentono alla visualizzazione di impostare i collegamenti ipertestuali dell'intestazione di colonna come indicato di seguito:These two statements enable the view to set the column heading hyperlinks as follows:

Ordinamento correnteCurrent sort order Collegamento ipertestuale cognomeLast Name Hyperlink Collegamento ipertestuale dataDate Hyperlink
Cognome in ordine crescenteLast Name ascending descendingdescending ascendingascending
Cognome in ordine decrescenteLast Name descending ascendingascending ascendingascending
Data in ordine crescenteDate ascending ascendingascending descendingdescending
Data in ordine decrescenteDate descending ascendingascending ascendingascending

Il metodo utilizza LINQ to Entities per specificare la colonna in base alla quale eseguire l'ordinamento.The method uses LINQ to Entities to specify the column to sort by. Il codice crea una variabile di IQueryable<T> prima dell'istruzione switch, la modifica nell'istruzione switch e chiama il metodo ToList dopo l'istruzione switch.The code creates an IQueryable<T> variable before the switch statement, modifies it in the switch statement, and calls the ToList method after the switch statement. Quando si creano e modificano variabili IQueryable, nessuna query viene inviata al database.When you create and modify IQueryable variables, no query is sent to the database. La query non viene eseguita finché non si converte l'oggetto IQueryable in una raccolta chiamando un metodo come ToList.The query is not executed until you convert the IQueryable object into a collection by calling a method such as ToList. Pertanto, questo codice genera una singola query che non viene eseguita fino all'istruzione return View.Therefore, this code results in a single query that is not executed until the return View statement.

In alternativa alla scrittura di istruzioni LINQ diverse per ogni ordinamento, è possibile creare dinamicamente un'istruzione LINQ.As an alternative to writing different LINQ statements for each sort order, you can dynamically create a LINQ statement. Per informazioni su LINQ dinamico, vedere Dynamic LINQ.For information about dynamic LINQ, see Dynamic LINQ.

  1. In Views\Student\Index.cshtmlsostituire gli elementi <tr> e <th> per la riga di intestazione con il codice evidenziato:In Views\Student\Index.cshtml, replace the <tr> and <th> elements for the heading row with the highlighted code:

    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
    <table class="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) {
    

    Questo codice usa le informazioni contenute nelle proprietà ViewBag per impostare i collegamenti ipertestuali con i valori della stringa di query appropriati.This code uses the information in the ViewBag properties to set up hyperlinks with the appropriate query string values.

  2. Eseguire la pagina e fare clic sulle intestazioni di colonna Last Name e Data di registrazione per verificare il corretto funzionamento dell'ordinamento.Run the page and click the Last Name and Enrollment Date column headings to verify that sorting works.

    Dopo aver fatto clic sull'intestazione Last Name , gli studenti vengono visualizzati in ordine decrescente in base al cognome.After you click the Last Name heading, students are displayed in descending last name order.

Per aggiungere filtri alla pagina di indice students, aggiungere una casella di testo e un pulsante Submit alla visualizzazione e apportare le modifiche corrispondenti nel metodo Index.To add filtering to the Students index page, you'll add a text box and a submit button to the view and make corresponding changes in the Index method. La casella di testo consente di immettere una stringa da cercare nei campi First Name e Last Name.The text box lets you enter a string to search for in the first name and last name fields.

Aggiungere la funzionalità di filtro al metodo IndexAdd filtering functionality to the Index method

  • In Controllers\StudentController.cssostituire il metodo Index con il codice seguente (le modifiche sono evidenziate):In Controllers\StudentController.cs, replace the Index method with the following code (the changes are highlighted):

    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.Contains(searchString)
                                   || s.FirstMidName.Contains(searchString));
        }
        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());
    }
    

Il codice aggiunge un parametro searchString al metodo Index.The code adds a searchString parameter to the Index method. Il valore della stringa di ricerca viene ricevuto da una casella di testo che verrà aggiunta alla visualizzazione Index (Indice).The search string value is received from a text box that you'll add to the Index view. Aggiunge anche una clausola where all'istruzione LINQ che seleziona solo gli studenti il cui nome o cognome contiene la stringa di ricerca.It also adds a where clause to the LINQ statement that selects only students whose first name or last name contains the search string. L'istruzione che aggiunge la clausola Where viene eseguita solo se è presente un valore da cercare.The statement that adds the Where clause executes only if there's a value to search for.

Note

In molti casi è possibile chiamare lo stesso metodo in un set di entità Entity Framework o come metodo di estensione in una raccolta in memoria.In many cases you can call the same method either on an Entity Framework entity set or as an extension method on an in-memory collection. I risultati sono in genere uguali, ma in alcuni casi potrebbero essere diversi.The results are normally the same but in some cases may be different.

Ad esempio, l'implementazione .NET Framework del metodo Contains restituisce tutte le righe quando viene passata una stringa vuota, ma il provider di Entity Framework per SQL Server Compact 4,0 restituisce zero righe per le stringhe vuote.For example, the .NET Framework implementation of the Contains method returns all rows when you pass an empty string to it, but the Entity Framework provider for SQL Server Compact 4.0 returns zero rows for empty strings. Di conseguenza, il codice nell'esempio, inserendo l'istruzione Where all'interno di un'istruzione if, garantisce di ottenere gli stessi risultati per tutte le versioni di SQL Server.Therefore the code in the example (putting the Where statement inside an if statement) makes sure that you get the same results for all versions of SQL Server. Inoltre, l'implementazione .NET Framework del metodo Contains esegue un confronto con distinzione tra maiuscole e minuscole per impostazione predefinita, ma Entity Framework i provider SQL Server eseguono confronti senza distinzione tra maiuscole e minuscole per impostazione predefinita.Also, the .NET Framework implementation of the Contains method performs a case-sensitive comparison by default, but Entity Framework SQL Server providers perform case-insensitive comparisons by default. Pertanto, chiamando il metodo ToUpper per fare in modo che il test senza distinzione tra maiuscole e minuscole garantisce che i risultati non cambiano quando si modifica il codice in un secondo momento per usare un repository, che restituirà una raccolta IEnumerable invece di un oggetto IQueryable.Therefore, calling the ToUpper method to make the test explicitly case-insensitive ensures that results do not change when you change the code later to use a repository, which will return an IEnumerable collection instead of an IQueryable object. Quando il metodo Contains viene chiamato su una raccolta IEnumerable, si ottiene l'implementazione di .NET Framework; quando viene chiamato su un oggetto IQueryable, si ottiene l'implementazione del provider di database.(When you call the Contains method on an IEnumerable collection, you get the .NET Framework implementation; when you call it on an IQueryable object, you get the database provider implementation.)

La gestione dei valori null può essere diversa anche per provider di database diversi o quando si usa un oggetto IQueryable rispetto a quando si usa una raccolta di IEnumerable.Null handling may also be different for different database providers or when you use an IQueryable object compared to when you use an IEnumerable collection. In alcuni scenari, ad esempio, una condizione Where come table.Column != 0 non può restituire colonne con null come valore.For example, in some scenarios a Where condition such as table.Column != 0 may not return columns that have null as the value. Per impostazione predefinita, EF genera operatori SQL aggiuntivi per far funzionare l'uguaglianza tra i valori null nel database come funziona in memoria, ma è possibile impostare il flag UseDatabaseNullSemantics in EF6 o chiamare il metodo UseRelationalNulls in EF core per configurare questo comportamento.By default, EF generates additional SQL operators to make equality between null values work in the database like it works in memory, but you can set the UseDatabaseNullSemantics flag in EF6 or call the UseRelationalNulls method in EF Core to configure this behavior.

Aggiungere una casella di ricerca alla visualizzazione dell'indice StudentAdd a search box to the Student index view

  1. In Views\Student\Index.cshtml, aggiungere il codice evidenziato immediatamente prima del tag di apertura table per creare una didascalia, una casella di testo e un pulsante di ricerca .In Views\Student\Index.cshtml, add the highlighted code immediately before the opening table tag in order to create a caption, a text box, and a Search button.

    <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>
    
  2. Eseguire la pagina, immettere una stringa di ricerca e fare clic su Cerca per verificare che il filtro sia funzionante.Run the page, enter a search string, and click Search to verify that filtering is working.

    Si noti che l'URL non contiene la stringa di ricerca "an", il che significa che se si aggiunge un segnalibro a questa pagina, non si otterrà l'elenco filtrato quando si usa il segnalibro.Notice the URL doesn't contain the "an" search string, which means that if you bookmark this page, you won't get the filtered list when you use the bookmark. Questo vale anche per i collegamenti di ordinamento delle colonne, in quanto verranno ordinati nell'intero elenco.This applies also to the column sort links, as they will sort the whole list. Il pulsante Cerca verrà modificato in modo da usare le stringhe di query per i criteri di filtro più avanti nell'esercitazione.You'll change the Search button to use query strings for filter criteria later in the tutorial.

Aggiungere la suddivisione in pagineAdd paging

Per aggiungere il paging alla pagina di indice students, iniziare installando il pacchetto NuGet PagedList. Mvc .To add paging to the Students index page, you'll start by installing the PagedList.Mvc NuGet package. Verranno quindi apportate altre modifiche nel metodo Index e verranno aggiunti collegamenti di paging alla visualizzazione Index.Then you'll make additional changes in the Index method and add paging links to the Index view. PagedList. Mvc è uno dei molti pacchetti di paging e ordinamento validi per ASP.NET MVC e il suo utilizzo è previsto solo come esempio, non come una raccomandazione per le altre opzioni.PagedList.Mvc is one of many good paging and sorting packages for ASP.NET MVC, and its use here is intended only as an example, not as a recommendation for it over other options.

Installare il pacchetto NuGet PagedList. MVCInstall the PagedList.MVC NuGet package

Il pacchetto NuGet PagedList. Mvc installa automaticamente il pacchetto PagedList come dipendenza.The NuGet PagedList.Mvc package automatically installs the PagedList package as a dependency. Il pacchetto PagedList installa un tipo di raccolta PagedList e i metodi di estensione per le raccolte IQueryable e IEnumerable.The PagedList package installs a PagedList collection type and extension methods for IQueryable and IEnumerable collections. I metodi di estensione creano una singola pagina di dati in una raccolta di PagedList fuori dall'IQueryable o IEnumerablee la raccolta di PagedList fornisce diverse proprietà e metodi che facilitano il paging.The extension methods create a single page of data in a PagedList collection out of your IQueryable or IEnumerable, and the PagedList collection provides several properties and methods that facilitate paging. Il pacchetto PagedList. Mvc installa un helper di paging che Visualizza i pulsanti di paging.The PagedList.Mvc package installs a paging helper that displays the paging buttons.

  1. Dal menu strumenti selezionare Gestione pacchetti NuGet e quindi Console di Gestione pacchetti.From the Tools menu, select NuGet Package Manager and then Package Manager Console.

  2. Nella finestra console di gestione pacchetti assicurarsi che l' origine del pacchetto sia NuGet.org e che il progetto predefinito sia ContosoUniversity, quindi immettere il comando seguente:In the Package Manager Console window, make sure the Package source is nuget.org and the Default project is ContosoUniversity, and then enter the following command:

    Install-Package PagedList.Mvc
    
  3. Compilare il progetto.Build the project.

Aggiungere la funzionalità di suddivisione in pagine al metodo IndexAdd paging functionality to the Index method

  1. In Controllers\StudentController.csaggiungere un'istruzione using per lo spazio dei nomi PagedList:In Controllers\StudentController.cs, add a using statement for the PagedList namespace:

    using PagedList;
    
  2. Sostituire il metodo Index con il codice seguente:Replace the Index method with the following code:

    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.Contains(searchString)
                                 || s.FirstMidName.Contains(searchString));
       }
       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));
    }
    

    Questo codice aggiunge un parametro page, un parametro di ordinamento corrente e un parametro di filtro corrente alla firma del metodo:This code adds a page parameter, a current sort order parameter, and a current filter parameter to the method signature:

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

    Quando la pagina viene visualizzata per la prima volta o se l'utente non ha fatto clic su un collegamento di paging o di ordinamento, tutti i parametri sono null.The first time the page is displayed, or if the user hasn't clicked a paging or sorting link, all the parameters are null. Se si fa clic su un collegamento di paging, la variabile page contiene il numero di pagina da visualizzare.If a paging link is clicked, the page variable contains the page number to display.

    Una proprietà ViewBag fornisce la visualizzazione con l'ordinamento corrente, perché deve essere incluso nei collegamenti di paging per mantenerlo nello stesso modo durante il paging:A ViewBag property provides the view with the current sort order, because this must be included in the paging links in order to keep the sort order the same while paging:

    ViewBag.CurrentSort = sortOrder;
    

    Un'altra proprietà, ViewBag.CurrentFilter, fornisce la visualizzazione con la stringa di filtro corrente.Another property, ViewBag.CurrentFilter, provides the view with the current filter string. Questo valore deve essere incluso nei collegamenti di suddivisione in pagine per mantenere le impostazioni di filtro nella suddivisione in pagine e deve essere ripristinato nella casella di testo quando la pagina viene nuovamente visualizzata.This value must be included in the paging links in order to maintain the filter settings during paging, and it must be restored to the text box when the page is redisplayed. Se la stringa di ricerca viene modificata nella suddivisione in pagine, la pagina deve essere reimpostata su 1, poiché il nuovo filtro può comportare la visualizzazione di dati diversi.If the search string is changed during paging, the page has to be reset to 1, because the new filter can result in different data to display. La stringa di ricerca viene modificata quando si immette un valore nella casella di testo e si preme il pulsante Invia.The search string is changed when a value is entered in the text box and the submit button is pressed. In tal caso, il parametro searchString non è null.In that case, the searchString parameter is not null.

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

    Alla fine del metodo, il metodo di estensione ToPagedList sull'oggetto students IQueryable converte la query Student in una singola pagina di students in un tipo di raccolta che supporta il paging.At the end of the method, the ToPagedList extension method on the students IQueryable object converts the student query to a single page of students in a collection type that supports paging. Questa singola pagina di studenti viene quindi passata alla visualizzazione:That single page of students is then passed to the view:

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

    Il metodo ToPagedList accetta un numero di pagina.The ToPagedList method takes a page number. I due punti interrogativi rappresentano l' operatore che unisce i valori null.The two question marks represent the null-coalescing operator. L'operatore null-coalescing definisce un valore predefinito per un tipo nullable. L'espressione (page ?? 1) significa restituzione del valore di page se ha un valore oppure restituzione di 1 se page è Null.The null-coalescing operator defines a default value for a nullable type; the expression (page ?? 1) means return the value of page if it has a value, or return 1 if page is null.

  1. In Views\Student\Index.cshtmlsostituire il codice esistente con il codice seguente.In Views\Student\Index.cshtml, replace the existing code with the following code. Le modifiche vengono evidenziate.The changes are highlighted.

    @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 class="table">
        <tr>
            <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>
            <th></th>
        </tr>
    
    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.LastName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.FirstMidName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.EnrollmentDate)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
                @Html.ActionLink("Details", "Details", new { id=item.ID }) |
                @Html.ActionLink("Delete", "Delete", new { id=item.ID })
            </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 }))
    

    L'istruzione @model nella parte superiore della pagina specifica che la vista ottiene ora un oggetto PagedList anziché un oggetto List.The @model statement at the top of the page specifies that the view now gets a PagedList object instead of a List object.

    L'istruzione using per PagedList.Mvc fornisce l'accesso all'helper MVC per i pulsanti di paging.The using statement for PagedList.Mvc gives access to the MVC helper for the paging buttons.

    Il codice usa un overload di BeginForm che consente di specificare FormMethod. Get.The code uses an overload of BeginForm that allows it to specify 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>
    }
    

    Il BeginForm predefinito invia i dati del modulo con un post, il che significa che i parametri vengono passati nel corpo del messaggio http e non nell'URL come stringhe di query.The default BeginForm submits form data with a POST, which means that parameters are passed in the HTTP message body and not in the URL as query strings. Quando si specifica HTTP GET, i dati del modulo vengono passati nell'URL come stringhe di query, il che consente agli utenti di inserire l'URL tra i segnalibri.When you specify HTTP GET, the form data is passed in the URL as query strings, which enables users to bookmark the URL. Le linee guida W3C per l'uso di http Get consiglia di usare Get quando l'azione non genera un aggiornamento.The W3C guidelines for the use of HTTP GET recommend that you should use GET when the action does not result in an update.

    La casella di testo viene inizializzata con la stringa di ricerca corrente, quindi quando si fa clic su una nuova pagina è possibile visualizzare la stringa di ricerca corrente.The text box is initialized with the current search string so when you click a new page you can see the current search string.

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

    I collegamenti delle intestazioni di colonna usano la stringa di query per passare la stringa di ricerca corrente al controller in modo che l'utente possa procedere all'ordinamento all'interno dei risultati di filtro:The column header links use the query string to pass the current search string to the controller so that the user can sort within filter results:

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

    Viene visualizzata la pagina corrente e il numero totale di pagine.The current page and total number of pages are displayed.

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

    Se non sono presenti pagine da visualizzare, viene visualizzato "pagina 0 di 0".If there are no pages to display, "Page 0 of 0" is shown. In tal caso, il numero di pagina è maggiore del conteggio delle pagine perché Model.PageNumber è 1 e Model.PageCount è 0.(In that case the page number is greater than the page count because Model.PageNumber is 1, and Model.PageCount is 0.)

    I pulsanti di paging vengono visualizzati dall'helper PagedListPager:The paging buttons are displayed by the PagedListPager helper:

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

    Il PagedListPager helper fornisce diverse opzioni che è possibile personalizzare, inclusi URL e stile.The PagedListPager helper provides a number of options that you can customize, including URLs and styling. Per ulteriori informazioni, vedere TroyGoode/PagedList nel sito github.For more information, see TroyGoode / PagedList on the GitHub site.

  2. Eseguire la pagina.Run the page.

    Fare clic sui collegamenti di suddivisione in pagine in diversi tipi di ordinamento per verificare che la suddivisione in pagine funzioni.Click the paging links in different sort orders to make sure paging works. Immettere quindi una stringa di ricerca e provare nuovamente la suddivisione in pagine per verificare che funzioni correttamente anche con l'ordinamento e il filtro.Then enter a search string and try paging again to verify that paging also works correctly with sorting and filtering.

Creare una pagina AboutCreate an About page

Per la pagina about del sito Web di Contoso University verrà visualizzato il numero di studenti iscritti per ogni data di registrazione.For the Contoso University website's About page, you'll display how many students have enrolled for each enrollment date. Questa operazione richiede calcoli di raggruppamento e semplici sui gruppi.This requires grouping and simple calculations on the groups. Per completare questa procedura, è necessario eseguire le operazioni seguenti:To accomplish this, you'll do the following:

  • Creare una classe modello di visualizzazione per i dati che è necessario passare alla visualizzazione.Create a view model class for the data that you need to pass to the view.
  • Modificare il metodo About nel controller Home.Modify the About method in the Home controller.
  • Modificare la visualizzazione About.Modify the About view.

Creare il modello di visualizzazioneCreate the View Model

Creare una cartella ViewModels nella cartella del progetto.Create a ViewModels folder in the project folder. In tale cartella aggiungere un file di classe EnrollmentDateGroup.cs e sostituire il codice del modello con il codice seguente:In that folder, add a class file EnrollmentDateGroup.cs and replace the template code with the following code:

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; }
    }
}

Modificare il controller HomeModify the Home Controller

  1. In HomeController.csaggiungere le istruzioni using seguenti all'inizio del file:In HomeController.cs, add the following using statements at the top of the file:

    using ContosoUniversity.DAL;
    using ContosoUniversity.ViewModels;
    
  2. Aggiungere una variabile di classe per il contesto di database immediatamente dopo la parentesi graffa di apertura per la classe:Add a class variable for the database context immediately after the opening curly brace for the class:

    public class HomeController : Controller
    {
        private SchoolContext db = new SchoolContext();
    
  3. Sostituire il metodo About con il codice seguente:Replace the About method with the following code:

    public ActionResult About()
    {
        IQueryable<EnrollmentDateGroup> 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.ToList());
    }
    

    L'istruzione LINQ raggruppa le entità di studenti per data di registrazione, calcola il numero di entità in ogni gruppo e archivia i risultati in una raccolta di oggetti di modello della visualizzazione EnrollmentDateGroup.The LINQ statement groups the student entities by enrollment date, calculates the number of entities in each group, and stores the results in a collection of EnrollmentDateGroup view model objects.

  4. Aggiungere un metodo di Dispose:Add a Dispose method:

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

Modificare la visualizzazione della pagina About (Informazioni)Modify the About View

  1. Sostituire il codice nel file Views\Home\About.cshtml con il codice seguente:Replace the code in the Views\Home\About.cshtml file with the following code:

    @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>
    
  2. Eseguire l'app e fare clic sul collegamento About (informazioni ).Run the app and click the About link.

    Il numero di studenti per ogni data di registrazione viene visualizzato in una tabella.The count of students for each enrollment date displays in a table.

    About_page

Ottenere il codiceGet the code

Scaricare il progetto completatoDownload the Completed Project

Risorse aggiuntiveAdditional resources

Collegamenti ad altre risorse Entity Framework sono disponibili in ASP.NET Data Access-risorse consigliate.Links to other Entity Framework resources can be found in ASP.NET Data Access - Recommended Resources.

Passaggi successiviNext steps

Le attività di questa esercitazione sono le seguenti:In this tutorial, you:

  • Aggiungere collegamenti per l'ordinamento delle colonneAdd column sort links
  • Aggiungere una casella di ricercaAdd a Search box
  • Aggiungere la suddivisione in pagineAdd paging
  • Creare una pagina AboutCreate an About page

Passare all'articolo successivo per informazioni su come usare la resilienza delle connessioni e l'intercettazione dei comandi.Advance to the next article to learn how to use connection resiliency and command interception.