Рассмотрим, как фильтровать данные по определенным критериям в ASP.NET Core MVC. Для работы возьмем следующие модели User и Company:
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; } = new(); }
Для взаимодействия с MS SQL Server через Entity Framework добавим в проект через Nuget пакет Microsoft.EntityFrameworkCore.SqlServer. А затем добавим в проект класс контекста данных UsersContext:
using Microsoft.EntityFrameworkCore; namespace MvcApp.Models { public class UsersContext : DbContext { public DbSet<User> Users { get; set; } = null!; public DbSet<Company> Companies { get; set; } = null!; public UsersContext(DbContextOptions<UsersContext> options) : base(options) { Database.EnsureCreated(); } } }
И в файле Program.cs настроим использование этого контекста данных:
using Microsoft.EntityFrameworkCore; using MvcApp.Models; var builder = WebApplication.CreateBuilder(args); string connection = "Server = (localdb)\\mssqllocaldb;Database = userstoredb;Trusted_Connection=true"; builder.Services.AddDbContext<UsersContext>(options => options.UseSqlServer(connection)); builder.Services.AddControllersWithViews(); var app = builder.Build(); app.MapDefaultControllerRoute(); app.Run();
Допустим, при выводе списка пользователей нам надо также предусмотреть возможность для их фильтрации по некоторым критериям, например, по компании и по имени. Так как мы будем выводить в одном представлении и список пользователей, и критерии для выбора, которые представляют список компаний и выбранное имя, то добавим в проект специальную модель:
using Microsoft.AspNetCore.Mvc.Rendering; namespace MvcApp.Models { public class UserListViewModel { public IEnumerable<User> Users { get; set; } = new List<User>(); public SelectList Companies { get; set; } = new SelectList(new List<Company>(), "Id", "Name"); public string? Name { get; set; } } }
Три свойства - для списка пользователей, компаний, введенного для поиска имени. Причем для компаний применяется объект SelectList.
Для вывода данных модели определим представление:
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @model MvcApp.Models.UserListViewModel <h2>Каталог пользователей</h2> <form method="get"> <div> <label>Имя: </label> <input asp-for="Name" /> <label>Компания: </label> <select name="company" asp-items="Model.Companies"></select> <input type="submit" value="Фильтр" /> </div> </form> <table> <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 Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.EntityFrameworkCore; using MvcApp.Models; namespace MvcApp.Controllers { public class HomeController : Controller { UsersContext db; public HomeController(UsersContext context) { db = context; // добавляем начальные данные при их отсутствии if (!db.Companies.Any()) { 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 }); UserListViewModel viewModel = new UserListViewModel { Users = users.ToList(), Companies = new SelectList(companies, "Id", "Name", company), 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, который передается в представление.