使用 C# 在 ASP.NET MVC 中使用多个参数过滤数据

Using multiple parameters for filtering data in ASP.NET MVC using C#

我正在做一个图书馆项目,您应该可以在其中按出版商、类别、星级、网站等筛选图书。

我想出了一个解决方案,但是它由多个 if 语句组成,如果我想在将来添加更多过滤器,我发现它的可扩展性不太好。

这是我的 BookController 中处理它的方法之一:

public IActionResult Index(int? id, string title, string forlag, int rating)
{
    //Search by title given by category id
    var list = (from ep in _db.Books
                join e in _db.BookCategories 
                on ep.BookID equals e.BookID
                where e.CategoryID == id && ep.Title.Contains($"{title}")
                select new Book
                {
                    BookID = ep.BookID,
                    Title = ep.Title,
                    Author = ep.Author,
                    Isbn = ep.Isbn,
                    Publisher = ep.Publisher,
                    Sites = ep.Sites,
                    ReleaseDate = ep.ReleaseDate,
                    Summary = ep.Summary,
                    Picture = ep.Picture,
                    AddedDate = ep.AddedDate,
                    Stars = ep.Stars,
                }).ToList();

    var queryID = (from u in _db.Books
                    join e in _db.BookCategories
                    on u.BookID equals e.BookID
                    where e.CategoryID == id
                    select new Book
                    {
                        BookID = u.BookID,
                        Title = u.Title,
                        Author = u.Author,
                        Isbn = u.Isbn,
                        Publisher = u.Publisher,
                        Sites = u.Sites,
                        ReleaseDate = u.ReleaseDate,
                        Summary = u.Summary,
                        Picture = u.Picture,
                        AddedDate = u.AddedDate,
                        Stars = (from c in _db.bookComments where c.BookID == u.BookID && c.IsApproved == true select c.Stars).Average(),
                    }).ToList();

    var queryID2 = (from u in _db.Books
                    select new Book
                    {
                        BookID = u.BookID,
                        Title = u.Title,
                        Author = u.Author,
                        Isbn = u.Isbn,
                        Publisher = u.Publisher,
                        Sites = u.Sites,
                        ReleaseDate = u.ReleaseDate,
                        Summary = u.Summary,
                        Picture = u.Picture,
                        AddedDate = u.AddedDate,
                        Stars = (from c in _db.bookComments where c.BookID == u.BookID && c.IsApproved == true select c.Stars).Average(),
                    }).ToList();


    var sortedID = queryID.Where(o => o.Stars >= rating);
    var sortedID2 = queryID2.Where(o => o.Stars >= rating);


    //Search by title if category id equals 0
    var bookList = _db.Books.Where(o => o.Title.Contains($"{title}"));

    //Sort by category, publisher & star rating
    if (id > 0 && forlag != null && rating > 0)
    {
        var newListus = sortedID.Where(o => o.Publisher == forlag);
        return View(newListus);
    }

    //Sort by publisher & star rating
    if (id == 0 && forlag != null && rating > 0)
    {
        var peter = sortedID2.Where(o => o.Publisher == forlag);
        return View(peter);
    }

    //Sort by category & publisher
    if (id > 0 && forlag != null)
    {
        var newList = list.Where(o => o.Publisher == forlag);
        return View(newList);
    }

    //Sort by category & star rating
    if (id > 0 && rating > 0)
    {
        return View(sortedID);
    }

    //Sort by star rating
    if (id == 0 && rating > 0)
    {
        return View(sortedID2);
    }

    //Sort by publisher
    if (id == 0 && forlag != null)
    {
        var bookListSorted = _db.Books.Where(o => o.Publisher == forlag);
        return View(bookListSorted);
    }
    if (id == 0)
    {
        return View(bookList);
    }

    return View(list);
}

任何更具可扩展性和更简单的解决方案将不胜感激。如果需要更多信息,请告诉我。

马特奥

可以使用LINQ的特征查询组合。

我已经定义了中间匿名 class 来处理 Book 和它的星星。

public IActionResult Index(int? id, string title, string forlag, int rating)
{
    // filterout by title and set stars to default value
    var books = _db.Books
        .Where(b => b.Title.Contains(title))
        .Select(b => new { Book = b, Stars = 0.0 });

    var isStarsDefined  = false;

    if (id.HasValue)
    {
        //Search by title given by category id and assign category's Starts
        books = 
            from b in books
            join c in _db.BookCategories on b.Book.BookID equals c.BookID
            where c.CategoryID == id
            select new { Book = b.Book, Stars = c.Starts };

        isStarsDefined  = true;
    }

    // additional filter by publisher
    if (forlag != null)
    {
        books = books.Where(b => b.Book.Publisher == forlag);
    }

    // well probably for result we need stars
    if (!isStarsDefined)
    {
        books = books.Select(b  => new 
        { 
            Book = b.Book, 
            Stars = _db.bookComments
                .Where(c => c.BookID == b.Book.BookID && c.IsApproved == true)
                .Select(c => c.Stars)
                .Average()
        })
    }

    // filter by rating
    if (rating > 0)
    {
        books = books.Where(b => b.Stars >= rating);
    }

    // make final projection to DTO
    var result = books
        .Select(b => new Book
        {
            BookID = b.Book.BookID,
            Title = b.Book.Title,
            Author = b.Book.Author,
            Isbn = b.Book.Isbn,
            Publisher = b.Book.Publisher,
            Sites = b.Book.Sites,
            ReleaseDate = b.Book.ReleaseDate,
            Summary = b.Book.Summary,
            Picture = b.Book.Picture,
            AddedDate = b.Book.AddedDate,
            Stars = b.Stars
        })
        .ToList();

    result View(result);
}

请注意,我是凭记忆写的所有内容,可能存在一些小的编译问题。此外,如果您在中间使用 ToList ,您将失败,一切都应该通过 IQueryable.

进行