Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
Рассмотрим, как фильтровать данные по определенным критериям в ASP.NET Core MVC. Для работы возьмем следующие модели:
public class User { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public int CompanyId { get; set; } public Company Company { get; set; } } public class Company { public int Id { get; set; } public string Name { get; set; } public List<User> Users { get; set; } public Company() { Users = new List<User>(); } }
Для взаимодействия с MS SQL Server через Entity Framework добавим в проект через Nuget пакет Microsoft.EntityFrameworkCore.SqlServer. А затем добавим в проект класс контекста данных UsersContext:
using Microsoft.EntityFrameworkCore; namespace FilterApp.Models { public class UsersContext : DbContext { public DbSet<User> Users { get; set; } public DbSet<Company> Companies { get; set; } public UsersContext(DbContextOptions<UsersContext> options) : base(options) { Database.EnsureCreated(); } } }
И в классе Startup методе ConfigureServices()
настроим использование этого контекста данных:
public void ConfigureServices(IServiceCollection services) { string connection = "Server=(localdb)\\mssqllocaldb; Database=userstoredb; Trusted_Connection=true;"; services.AddDbContext<UsersContext>(options => options.UseSqlServer(connection)); services.AddControllersWithViews(); }
Допустим, при выводе списка пользователей нам надо также предусмотреть возможность для их фильтрации по некоторым критериям, например, по компании и по имени. Так как мы будем выводить в одном представлении и список пользователей, и критерии для выбора, которые представляют список компаний и выбранное имя, то добавим в проект специальную модель:
using Microsoft.AspNetCore.Mvc.Rendering; using System.Collections.Generic; namespace FilterApp.Models { public class UserListViewModel { public IEnumerable<User> Users { get; set; } public SelectList Companies { get; set; } public string Name { get; set; } } }
Три свойства - для списка пользователей, компаний, введенного для поиска имени.
Для вывода данных модели определим представление:
@model FilterApp.Models.UserListViewModel @{ ViewBag.Title = "Каталог пользователей"; } <h2>Каталог пользователей</h2> <form method="get"> <div class="form-inline form-group"> <label class="control-label">Имя: </label> <input name="name" class="form-control" /> <label class="control-label">Компания: </label> <select name="company" asp-items="Model.Companies" class="form-control"></select> <input type="submit" value="Фильтр" class="btn btn-default" /> </div> </form> <table class="table table-striped"> <tr> <th>Имя</th> <th>Возраст</th> <th>Компания</th> </tr> @foreach (var item in Model.Users) { <tr> <td>@item.Name</td> <td>@item.Age</td> <td>@item.Company.Name</td> </tr> } </table>
Перед таблицей со списком пользователей, определена форма, которая с помощью запросов GET посылает введенные значения на сервер.
Теперь на стороне контроллера определим метод, который будет выводить список пользователей и производить фильтрацию:
using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc; using FilterApp.Models; using Microsoft.EntityFrameworkCore; using Microsoft.AspNetCore.Mvc.Rendering; namespace FilterApp.Controllers { public class HomeController : Controller { UsersContext db; public HomeController(UsersContext context) { db = context; // добавляем начальные данные if (db.Companies.Count() == 0) { Company oracle = new Company { Name = "Oracle" }; Company google = new Company { Name = "Google" }; Company microsoft = new Company { Name = "Microsoft" }; Company apple = new Company { Name = "Apple" }; User user1 = new User { Name = "Олег Васильев", Company = oracle, Age = 26 }; User user2 = new User { Name = "Александр Овсов", Company = oracle, Age = 24 }; User user3 = new User { Name = "Алексей Петров", Company = microsoft, Age = 25 }; User user4 = new User { Name = "Иван Иванов", Company = microsoft, Age = 26 }; User user5 = new User { Name = "Петр Андреев", Company = microsoft, Age = 23 }; User user6 = new User { Name = "Василий Иванов", Company = google, Age = 23 }; User user7 = new User { Name = "Олег Кузнецов", Company = google, Age = 25 }; User user8 = new User { Name = "Андрей Петров", Company = apple, Age = 24 }; db.Companies.AddRange(oracle, microsoft, google, apple); db.Users.AddRange(user1, user2, user3, user4, user5, user6, user7, user8); db.SaveChanges(); } } public ActionResult Index(int? company, string name) { IQueryable<User> users = db.Users.Include(p => p.Company); if (company != null && company != 0) { users = users.Where(p => p.CompanyId == company); } if (!String.IsNullOrEmpty(name)) { users = users.Where(p => p.Name.Contains(name)); } List<Company> companies = db.Companies.ToList(); // устанавливаем начальный элемент, который позволит выбрать всех companies.Insert(0, new Company { Name = "Все", Id = 0 }); UsersListViewModel viewModel = new UsersListViewModel { Users = users.ToList(), Companies = new SelectList(companies, "Id", "Name"), Name = name }; return View(viewModel); } } }
При обращении к методу Index вне зависимости были ли переданы параметры name и company, все равно в представление будет выводиться список пользователей.
Если определенный параметр был передан, то к объекту IQueryable, представляющего выборку, добавляется выражение Where:
users = users.Where(p => p.CompanyId == company);
.
Для формирования выпадающего списка компаний в представлении, получаем его из БД:
List<Company> companies = db.Companies.ToList();
Для возможности выбора пользователей из любой компании, добавляем в этот список новый пункт:
companies.Insert(0, new Company { Name = "Все", Id = 0 });
Все полученные данные используются для формирования объекта UserListViewModel, который передается в представление.