Фильтрация данных внутри. NET основных контроллеров - PullRequest
1 голос
/ 06 августа 2020

Итак, я хочу применить разные фильтры к определенному набору данных из базы данных, скажем, я хочу получить только фильмы определенного жанра и на основе этих отфильтрованных данных выполнить поиск определенного mov ie по его имя из отфильтрованных фильмов. В этом руководстве здесь они выполняют фильтрацию данных (фильмов) всего за 1 щелчок кнопки с помощью функции индекса.

public async Task<IActionResult> Index(string movieGenre, string searchString)
        {
            // Use LINQ to get list of genres.
            IQueryable<string> genreQuery = from m in _context.Movie
                                            orderby m.Genre
                                            select m.Genre;

            var movies = from m in _context.Movie
                         select m;

            if (!string.IsNullOrEmpty(searchString))
            {
                movies = movies.Where(s => s.Title.Contains(searchString));
            }

            if (!string.IsNullOrEmpty(movieGenre))
            {
                movies = movies.Where(x => x.Genre == movieGenre);
            }

            var movieGenreVM = new MovieGenreViewModel
            {
                Genres = new SelectList(await genreQuery.Distinct().ToListAsync()),
                Movies = await movies.ToListAsync()
            };

            return View(movieGenreVM);
        }

И вид:

<form asp-controller="Movies" asp-action="Index" method="get">
    <p>

        <select asp-for="MovieGenre" asp-items="Model.Genres">
            <option value="">All</option>
        </select>

        Title: <input type="text" asp-for="SearchString" />
        <input type="submit" value="Filter" />
    </p>
</form>

Но что мне делать, если я хочу иметь разные кнопки для разных типов фильтрации и хочу выполнить вторую фильтрацию для уже отфильтрованных данных с помощью первой кнопки. Как мне получить эти предыдущие данные, которые уже были отфильтрованы, чтобы отфильтровать их еще больше?

Если я сделаю что-то вроде этого:

<form asp-controller="Movies" asp-action="Index" method="get">
    <p>

        <select asp-for="MovieGenre" asp-items="Model.Genres">
            <option value="">All</option>
        </select>

        <input type="submit" value="Filter" />
    </p>
</form>

<form asp-controller="Movies" asp-action="Index" method="get">
    <p>


        Title: <input type="text" asp-for="SearchString" />
        <input type="submit" value="Filter" />
    </p>
</form>

Тогда я не могу просто выбрать mov ie жанр, отфильтруйте, затем выберите строку поиска и выполните поиск по уже отфильтрованным фильмам, потому что я всегда буду получать полные данные из базы данных при каждом вызове функции.

1 Ответ

1 голос
/ 06 августа 2020

Вы можете добавить все фильтры в метод Index. Index(FilterModel model)

public class FilterModel
{
     public FilterType Filter {get;set;}
     public string Filter1..
     public string Filter2..
     etc..
}

public enum FilterType { ByName, ByDate, etc... }

На основе значения перечисления, которое должно передаваться при нажатии кнопки, вы можете создать Expression<Func<TModel, bool>> predicate и передать его в предложение Where().

В качестве example

Expression<Func<TModel, bool>> predicate = x => true;

if(model.Filter == FilterType.ByName)
{
    predicate = x => x.Name == moedl.Filter1;
} 
else
{
}

var filtered = dbContext.Movies.Where(predicate);
..

Это просто пример, чтобы дать представление о том, как вы можете его улучшить. Но я обычно использую перечисления для определения фильтрации, которую я хочу выполнить.

Значение перечисления должно поступать из представления, если у вас есть несколько представлений с разными формами, вы можете жестко закодировать значение перечисления в форме, используя скрытое поле, иначе, возможно, поможет раскрывающийся список.

Вы можете использовать тот же метод для POST, GET, но обязательно проверьте наличие model != null. Если null - не фильтруйте.

Другой вариант - немного улучшить FilterModel и использовать Dictionary<string, string> Values вместо Filter1, Filter2 et c, но это зависит от сложности использования case.

Извините, я не смог доказать более реалистичный c пример, но надеюсь, что это ведет в правильном направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...