Udostępnij za pośrednictwem


Używanie programu Entity Framework 4.0 i kontrolki ObjectDataSource, część 3: sortowanie i filtrowanie

Autor : Tom Dykstra

Ta seria samouczków jest oparta na aplikacji internetowej Contoso University utworzonej przez Wprowadzenie z serii samouczków platformy Entity Framework 4.0. Jeśli nie wykonasz wcześniejszych samouczków, jako punkt wyjścia dla tego samouczka możesz pobrać utworzoną aplikację . Możesz również pobrać aplikację utworzoną w ramach pełnej serii samouczków. Jeśli masz pytania dotyczące samouczków, możesz opublikować je na forum ASP.NET Entity Framework.

W poprzednim samouczku zaimplementowano wzorzec repozytorium w n-warstwowej aplikacji internetowej korzystającej z programu Entity Framework i kontrolki ObjectDataSource . W tym samouczku pokazano, jak sortować i filtrować i obsługiwać scenariusze szczegółów głównych. Do strony Departments.aspx dodasz następujące ulepszenia:

  • Pole tekstowe umożliwiające użytkownikom wybieranie działów według nazwy.
  • Lista kursów dla każdego działu, który jest wyświetlany w siatce.
  • Możliwość sortowania przez kliknięcie nagłówków kolumn.

Zrzut ekranu przedstawiający stronę Działy gotową do ulepszeń.

Dodawanie możliwości sortowania kolumn GridView

Otwórz stronę Departments.aspx i dodaj SortParameterName="sortExpression" atrybut do kontrolki ObjectDataSource o nazwie DepartmentsObjectDataSource. (Później utworzysz metodę GetDepartments , która przyjmuje parametr o nazwie sortExpression.) Znaczniki dla tagu otwierającego kontrolki są teraz podobne do poniższego przykładu.

<asp:ObjectDataSource ID="DepartmentsObjectDataSource" runat="server" 
        TypeName="ContosoUniversity.BLL.SchoolBL" DataObjectTypeName="ContosoUniversity.DAL.Department" 
        SelectMethod="GetDepartments" DeleteMethod="DeleteDepartment" UpdateMethod="UpdateDepartment"
        ConflictDetection="CompareAllValues" OldValuesParameterFormatString="orig{0}" 
        OnUpdated="DepartmentsObjectDataSource_Updated" SortParameterName="sortExpression" >

AllowSorting="true" Dodaj atrybut do tagu otwierającego kontrolkiGridView. Znaczniki dla tagu otwierającego kontrolki są teraz podobne do poniższego przykładu.

<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
        DataSourceID="DepartmentsObjectDataSource" DataKeyNames="DepartmentID" 
        OnRowUpdating="DepartmentsGridView_RowUpdating"
        AllowSorting="true" >

W pliku Departments.aspx.cs ustaw domyślną kolejność sortowania, wywołując GridView metodę kontrolki Sort z Page_Load metody :

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        DepartmentsGridView.Sort("Name", SortDirection.Ascending);
    }
}

Możesz dodać kod, który sortuje lub filtruje w klasie logiki biznesowej lub klasie repozytorium. Jeśli to zrobisz w klasie logiki biznesowej, po pobraniu danych z bazy danych zostaną wykonane zadania sortowania lub filtrowania, ponieważ klasa logiki biznesowej pracuje z obiektem zwróconym IEnumerable przez repozytorium. Jeśli dodasz kod sortowania i filtrowania w klasie repozytorium i zrobisz to przed przekonwertowaniem zapytania LINQ lub obiektu na IEnumerable obiekt, polecenia zostaną przekazane do bazy danych na potrzeby przetwarzania, co jest zwykle bardziej wydajne. W tym samouczku zaimplementujesz sortowanie i filtrowanie w sposób, który powoduje wykonanie przetwarzania przez bazę danych — czyli w repozytorium.

Aby dodać możliwość sortowania, należy dodać nową metodę do interfejsu repozytorium i klas repozytorium, a także do klasy logiki biznesowej. W pliku ISchoolRepository.cs dodaj nową GetDepartments metodę, która przyjmuje sortExpression parametr, który będzie używany do sortowania listy zwróconych działów:

IEnumerable<Department> GetDepartments(string sortExpression);

Parametr sortExpression określi kolumnę do sortowania i kierunek sortowania.

Dodaj kod dla nowej metody do pliku SchoolRepository.cs :

public IEnumerable<Department> GetDepartments(string sortExpression)
{
    if (String.IsNullOrWhiteSpace(sortExpression))
    {
        sortExpression = "Name";
    }
    return context.Departments.Include("Person").OrderBy("it." + sortExpression).ToList();
}

Zmień istniejącą metodę bez GetDepartments parametrów, aby wywołać nową metodę:

public IEnumerable<Department> GetDepartments()
{
    return GetDepartments("");
}

W projekcie testowym dodaj następującą nową metodę do pliku MockSchoolRepository.cs:

public IEnumerable<Department> GetDepartments(string sortExpression)
{
    return departments;
}

Jeśli zamierzasz utworzyć dowolne testy jednostkowe, które były zależne od tej metody zwracającej posortowaną listę, należy posortować listę przed zwróceniem jej. W tym samouczku nie będziesz tworzyć testów, więc metoda może po prostu zwrócić nieortowaną listę działów.

W pliku SchoolBL.cs dodaj następującą nową metodę do klasy logiki biznesowej:

public IEnumerable<Department> GetDepartments(string sortExpression)
{
    return schoolRepository.GetDepartments(sortExpression);
}

Ten kod przekazuje parametr sortowania do metody repozytorium.

Uruchom stronę Departments.aspx .

Obraz02

Teraz możesz kliknąć dowolny nagłówek kolumny, aby posortować według tej kolumny. Jeśli kolumna jest już posortowana, kliknięcie nagłówka odwraca kierunek sortowania.

W tej sekcji dodasz pole tekstowe wyszukiwania, połączysz je ObjectDataSource z kontrolką przy użyciu parametru kontrolki i dodasz metodę do klasy logiki biznesowej w celu obsługi filtrowania.

Otwórz stronę Departments.aspx i dodaj następujący znacznik między nagłówkiem a pierwszą ObjectDataSource kontrolką:

Enter any part of the name or leave the box blank to see all names:
    <asp:TextBox ID="SearchTextBox" runat="server" AutoPostBack="true"></asp:TextBox>
     <asp:Button ID="SearchButton" runat="server" Text="Search" />

W kontrolce ObjectDataSource o nazwie DepartmentsObjectDataSourcewykonaj następujące czynności:

  • SelectParameters Dodaj element parametru o nazwie nameSearchString , który pobiera wartość wprowadzoną w kontrolceSearchTextBox.
  • Zmień wartość atrybutu SelectMethod na GetDepartmentsByName. (Ta metoda zostanie utworzona później).

Znaczniki dla kontrolki ObjectDataSource są teraz podobne do następującego przykładu:

<asp:ObjectDataSource ID="DepartmentsObjectDataSource" runat="server" TypeName="ContosoUniversity.BLL.SchoolBL"
        SelectMethod="GetDepartmentsByName" DeleteMethod="DeleteDepartment" UpdateMethod="UpdateDepartment"
        DataObjectTypeName="ContosoUniversity.DAL.Department" ConflictDetection="CompareAllValues"
        SortParameterName="sortExpression" OldValuesParameterFormatString="orig{0}" 
        OnUpdated="DepartmentsObjectDataSource_Updated">
        <SelectParameters>
            <asp:ControlParameter ControlID="SearchTextBox" Name="nameSearchString" PropertyName="Text"
                Type="String" />
        </SelectParameters>
    </asp:ObjectDataSource>

W pliku ISchoolRepository.cs dodaj metodę GetDepartmentsByName , która przyjmuje parametry i sortExpressionnameSearchString :

IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString);

W pliku SchoolRepository.cs dodaj następującą nową metodę:

public IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString)
{
    if (String.IsNullOrWhiteSpace(sortExpression))
    {
        sortExpression = "Name";
    }
    if (String.IsNullOrWhiteSpace(nameSearchString))
    {
        nameSearchString = "";
    }
    return context.Departments.Include("Person").OrderBy("it." + sortExpression).Where(d => d.Name.Contains(nameSearchString)).ToList();
}

Ten kod używa metody do wybierania Where elementów zawierających ciąg wyszukiwania. Jeśli ciąg wyszukiwania jest pusty, zostaną wybrane wszystkie rekordy. Należy pamiętać, że po określeniu metody w jednej instrukcji takiej jak ta (Include, a następnie OrderBy, Where ), Wheremetoda musi zawsze być ostatnia.

Zmień istniejącą GetDepartmentssortExpression metodę, która przyjmuje parametr w celu wywołania nowej metody:

public IEnumerable<Department> GetDepartments(string sortExpression)
{
    return GetDepartmentsByName(sortExpression, "");
}

W pliku MockSchoolRepository.cs w projekcie testowym dodaj następującą nową metodę:

public IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString)
{
    return departments;
}

W pliku SchoolBL.cs dodaj następującą nową metodę:

public IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString)
{
    return schoolRepository.GetDepartmentsByName(sortExpression, nameSearchString);
}

Uruchom stronę Departments.aspx i wprowadź ciąg wyszukiwania, aby upewnić się, że logika wyboru działa. Pozostaw puste pole tekstowe i spróbuj wyszukać, aby upewnić się, że wszystkie rekordy są zwracane.

Obraz03

Dodawanie kolumny szczegółów dla każdego wiersza siatki

Następnie chcesz zobaczyć wszystkie kursy dla każdego działu wyświetlanego w prawej komórce siatki. W tym celu użyjesz zagnieżdżonej GridView kontrolki i powiązania jej z danymi z Courses właściwości Department nawigacji jednostki.

Otwórz plik Departments.aspx i w narzucie dla kontrolki GridView określ procedurę obsługi dla RowDataBound zdarzenia. Znaczniki dla tagu otwierającego kontrolki są teraz podobne do poniższego przykładu.

<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
        DataSourceID="DepartmentsObjectDataSource" DataKeyNames="DepartmentID" 
        OnRowUpdating="DepartmentsGridView_RowUpdating"
        OnRowDataBound="DepartmentsGridView_RowDataBound"
        AllowSorting="True" >

Dodaj nowy TemplateField element po polu szablonu Administrator :

<asp:TemplateField HeaderText="Courses">
                <ItemTemplate>
                    <asp:GridView ID="CoursesGridView" runat="server" AutoGenerateColumns="False">
                        <Columns>
                            <asp:BoundField DataField="CourseID" HeaderText="ID" />
                            <asp:BoundField DataField="Title" HeaderText="Title" />
                        </Columns>
                    </asp:GridView>
                </ItemTemplate>
            </asp:TemplateField>

Ten znacznik tworzy zagnieżdżoną GridView kontrolkę, która pokazuje numer kursu i tytuł listy kursów. Nie określa źródła danych, ponieważ będzie on bindowany w kodzie w procedurze RowDataBound obsługi.

Otwórz plik Departments.aspx.cs i dodaj następującą procedurę obsługi dla zdarzenia RowDataBound :

protected void DepartmentsGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        var department = e.Row.DataItem as Department;
        var coursesGridView = (GridView)e.Row.FindControl("CoursesGridView");
        coursesGridView.DataSource = department.Courses.ToList();
        coursesGridView.DataBind();
    }
}

Ten kod pobiera Department jednostkę z argumentów zdarzeń, konwertuje Courses właściwość nawigacji na List kolekcję, a powiązanie danych zagnieżdżonych GridView do kolekcji.

Otwórz plik SchoolRepository.cs i określ chętne ładowanie właściwości Courses nawigacji, wywołując metodę Include w zapytaniu obiektu utworzonym w metodzie GetDepartmentsByName . Instrukcja return w metodzie GetDepartmentsByName jest teraz podobna do poniższego przykładu.

return context.Departments.Include("Person").Include("Courses").
    OrderBy("it." + sortExpression).Where(d => d.Name.Contains(nameSearchString)).ToList();

Uruchom stronę. Oprócz dodanej wcześniej możliwości sortowania i filtrowania kontrolka GridView wyświetla teraz zagnieżdżone szczegóły kursu dla każdego działu.

Zrzut ekranu przedstawiający kontrolkę Widok siatki wyświetlającą szczegóły zagnieżdżonego kursu.

Spowoduje to ukończenie wprowadzenia do scenariuszy sortowania, filtrowania i szczegółów głównych. W następnym samouczku zobaczysz, jak obsługiwać współbieżność.