Фильтрация

Последнее обновление: 12.04.2022

Рассмотрим, как фильтровать данные по определенным критериям в 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, который передается в представление.

Фильтрация в Entity Framework в ASP.NET Core MVC и C#
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850