/
IVEinzelstreife
/
CSharp_with_LINQ_in_ASPNETCore
Обзор
Документация
Войти
/
IVEinzelstreife
/
CSharp_with_LINQ_in_ASPNETCore
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Controllers/BooksController.cs
292 строки
10 KB
Илья Куракин
Загрузить файлы в «»
21 июл 2026, 10:36
Верифицирован
21 июл 2026, 10:36
e9e7fea
Код
Авторство
О чём код?
using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using BookStore.Data; using BookStore.Models; namespace BookStore.Controllers { [ApiController] [Route("api/[controller]")] public class BooksController : ControllerBase { private readonly ApplicationDbContext _context; public BooksController(ApplicationDbContext context) { _context = context; } // Получение всех книг с возможностью фильтрации [HttpGet] public async Task<IActionResult> GetAllBooks( [FromQuery] string? genre = null, [FromQuery] string? author = null, [FromQuery] decimal? minPrice = null, [FromQuery] decimal? maxPrice = null, [FromQuery] bool? inStock = null ) { // Начало запроса var query = _context.Books.AsQueryable(); // Динамическая фильтрация с LINQ if (!string.IsNullOrEmpty(genre)) { query = query.Where(b => b.Genre.Contains(genre)); } if (!string.IsNullOrEmpty(author)) { query = query.Where(b => b.Author.Contains(author)); } if (minPrice.HasValue) { query = query.Where(b => b.Price >= minPrice.Value); } if (maxPrice.HasValue) { query = query.Where(b => b.Price <= maxPrice.Value); } if (inStock.HasValue) { query = query.Where(b => inStock.Value ? b.StockQuantity > 0 : b.StockQuantity == 0); } // Выполнение запроса с проекцией var books = await query .Select(b => new { b.Id, b.Title, b.Author, b.Price, b.Year, b.Genre, b.StockQuantity, b.IsAvailable, // Форматирование статуса для удобства Status = b.StockQuantity > 0 ? "В наличии" : "Нет в наличии" }) .OrderBy(b => b.Author) .ThenBy(b => b.Title) .ToListAsync(); return Ok(new { TotalCount = books.Count, Books = books }); } // Получение конкретной книги [HttpGet("{id}")] public async Task<IActionResult> GetBook(int id) { var book = await _context.Books .Where(b => b.Id == id) .Select(b => new { b.Id, b.Title, b.Author, b.Price, b.Year, b.Genre, b.StockQuantity, b.IsAvailable }) .FirstOrDefaultAsync(); if (book == null) return NotFound($"Книга с ID {id} не найдена."); return Ok(book); } // Статистика по книгам [HttpGet("statistics")] public async Task<IActionResult> GetBookStatistics() { var stats = await _context.Books .GroupBy(b => 1) .Select(g => new { TotalBooks = g.Count(), TotalAuthors = g.Select(b => b.Author).Distinct().Count(), AveragePrice = g.Average(b => b.Price), MaxPrice = g.Max(b => b.Price), MinPrice = g.Min(b => b.Price), BooksInStock = g.Count(b => b.StockQuantity > 0), TotalStockValue = g.Sum(b => b.Price * b.StockQuantity) }) .FirstOrDefaultAsync(); // Статистика по жанрам var genreStats = await _context.Books .GroupBy(b => b.Genre) .Select(g => new { Genre = g.Key, BookCount = g.Count(), AveragePrice = g.Average(b => b.Price), TotalStock = g.Sum(b => b.StockQuantity) }) .OrderByDescending(g => g.BookCount) .ToListAsync(); return Ok(new { Overall = stats, ByGenre = genreStats }); } // Расширенный поиск с несколькими параметрами [HttpPost("search")] public async Task<IActionResult> SearchBooks([FromBody] SearchRequest request) { var query = _context.Books.AsQueryable(); // Использование LINQ для построения сложного поиска if (!string.IsNullOrEmpty(request.SearchTerm)) { var term = request.SearchTerm.ToLower(); query = query.Where(b => b.Title.ToLower().Contains(term) || b.Author.ToLower().Contains(term) || b.Genre.ToLower().Contains(term)); } if (request.YearFrom.HasValue) query = query.Where(b => b.Year >= request.YearFrom.Value); if (request.YearTo.HasValue) query = query.Where(b => b.Year <= request.YearTo.Value); if (request.PriceFrom.HasValue) query = query.Where(b => b.Price >= request.PriceFrom.Value); if (request.PriceTo.HasValue) query = query.Where(b => b.Price <= request.PriceTo.Value); // Сортировка if (!string.IsNullOrEmpty(request.SortBy)) { query = request.SortBy.ToLower() switch { "title" => request.Ascending ? query.OrderBy(b => b.Title) : query.OrderByDescending(b => b.Title), "author" => request.Ascending ? query.OrderBy(b => b.Author) : query.OrderByDescending(b => b.Author), "price" => request.Ascending ? query.OrderBy(b => b.Price) : query.OrderByDescending(b => b.Price), "year" => request.Ascending ? query.OrderBy(b => b.Year) : query.OrderByDescending(b => b.Year), _ => query.OrderBy(b => b.Id) }; } else { query = query.OrderBy(b => b.Id); } // Пагинация var page = request.Page > 0 ? request.Page : 1; var pageSize = request.PageSize > 0 ? request.PageSize : 10; var totalCount = await query.CountAsync(); var items = await query .Skip((page - 1) * pageSize) .Take(pageSize) .Select(b => new { b.Id, b.Title, b.Author, b.Price, b.Year, b.Genre, b.StockQuantity }) .ToListAsync(); return Ok(new { items = items, TotalCount = totalCount, CurrentPage = page, PageSize = pageSize, TotalPages = (int)Math.Ceiling(totalCount / (double)pageSize) }); } // Обновление количества книг на складе [HttpPut("{id}/stock")] public async Task<IActionResult> UpdateStock(int id, [FromBody] int newQuantity) { var book = await _context.Books.FindAsync(id); if (book == null) return NotFound($"Книга с ID {id} не найдена"); book.StockQuantity = newQuantity; book.IsAvailable = newQuantity > 0; await _context.SaveChangesAsync(); return Ok(new { Id = book.Id, Title = book.Title, NewStock = book.StockQuantity, IsAvailable = book.IsAvailable }); } // Получение доступных книг (с деталями) [HttpGet("available")] public async Task<IActionResult> GetAvailableBooks() { var availableBooks = await _context.Books .Where(b => b.StockQuantity > 0) .OrderByDescending(b => b.Price) .Select(b => new { b.Id, b.Title, b.Author, b.Price, b.Genre, b.Year, AvailableCopies = b.StockQuantity }) .ToListAsync(); // Дополнительная статистика с LINQ var summary = new { TotalAvailable = availableBooks.Count, TotalValue = availableBooks.Sum(b => b.Price), ByGenre = availableBooks .GroupBy(b => b.Genre) .Select(g => new { Genre = g.Key, Count = g.Count(), AveragePrice = g.Average(b => b.Price) }) .ToList() }; return Ok(new { Books = availableBooks, Summary = summary }); } } // Модель для запроса поиска public class SearchRequest { public string? SearchTerm { get; set; } public int? YearFrom { get; set; } public int? YearTo { get; set; } public decimal? PriceFrom { get; set; } public decimal? PriceTo { get; set; } public string? SortBy { get; set; } public bool Ascending { get; set; } = true; public int Page { get; set; } = 1; public int PageSize { get; set; } = 10; } }