Для создания CRUD операций в ASP.NET Core 8 MVC с использованием AutoMapper, паттернов Репозиторий и UnitOfWork, а также ViewModels, мы можем следовать следующему подходу. Я предоставлю пример кода для контроллера, репозитория, UnitOfWork, ViewModels и представлений.
1. Модель данных
Сначала создадим модель данных, которая будет представлять структуру таблицы.
public class CostItem
{
public int Id { get; set; }
public string NodeCode { get; set; }
public string CostName { get; set; }
public string CommentISR { get; set; }
public string ContractorComment { get; set; }
public string UnitOfMeasure { get; set; }
public decimal ConsumptionCoefficient { get; set; }
public int BaseObjectCount { get; set; }
public int TotalCount { get; set; }
public decimal PriceWithVAT { get; set; }
public decimal PriceWithoutVAT { get; set; }
public int ProjectCode { get; set; } // Код проекта
}
2. ViewModel
Создадим ViewModel для передачи данных между контроллером и представлениями.
public class CostItemViewModel
{
public int Id { get; set; }
public string NodeCode { get; set; }
public string CostName { get; set; }
public string CommentISR { get; set; }
public string ContractorComment { get; set; }
public string UnitOfMeasure { get; set; }
public decimal ConsumptionCoefficient { get; set; }
public int BaseObjectCount { get; set; }
public int TotalCount { get; set; }
public decimal PriceWithVAT { get; set; }
public decimal PriceWithoutVAT { get; set; }
public int ProjectCode { get; set; }
}
3. Репозиторий
Создадим интерфейс и реализацию репозитория.
public interface ICostItemRepository
{
Task<IEnumerable<CostItem>> GetAllAsync();
Task<CostItem> GetByIdAsync(int id);
Task AddAsync(CostItem costItem);
Task UpdateAsync(CostItem costItem);
Task DeleteAsync(int id);
}
public class CostItemRepository : ICostItemRepository
{
private readonly ApplicationDbContext _context;
public CostItemRepository(ApplicationDbContext context)
{
_context = context;
}
public async Task<IEnumerable<CostItem>> GetAllAsync()
{
return await _context.CostItems.ToListAsync();
}
public async Task<CostItem> GetByIdAsync(int id)
{
return await _context.CostItems.FindAsync(id);
}
public async Task AddAsync(CostItem costItem)
{
await _context.CostItems.AddAsync(costItem);
await _context.SaveChangesAsync();
}
public async Task UpdateAsync(CostItem costItem)
{
_context.CostItems.Update(costItem);
await _context.SaveChangesAsync();
}
public async Task DeleteAsync(int id)
{
var costItem = await GetByIdAsync(id);
if (costItem != null)
{
_context.CostItems.Remove(costItem);
await _context.SaveChangesAsync();
}
}
}
4. UnitOfWork
Создадим интерфейс и реализацию UnitOfWork.
public interface IUnitOfWork
{
ICostItemRepository CostItems { get; }
Task SaveAsync();
}
public class UnitOfWork : IUnitOfWork
{
private readonly ApplicationDbContext _context;
public ICostItemRepository CostItems { get; private set; }
public UnitOfWork(ApplicationDbContext context)
{
_context = context;
CostItems = new CostItemRepository(_context);
}
public async Task SaveAsync()
{
await _context.SaveChangesAsync();
}
}
5. Контроллер
Теперь создадим контроллер для управления CRUD операциями.
[Route("api/[controller]")]
[ApiController]
public class CostItemsController : Controller
{
private readonly IUnitOfWork _unitOfWork;
private readonly IMapper _mapper;
public CostItemsController(IUnitOfWork unitOfWork, IMapper mapper)
{
_unitOfWork = unitOfWork;
_mapper = mapper;
}
[HttpGet]
public async Task<IActionResult> Index()
{
var costItems = await _unitOfWork.CostItems.GetAllAsync();
var costItemViewModels = _mapper.Map<IEnumerable<CostItemViewModel>>(costItems);
return View(costItemViewModels);
}
[HttpGet("Create")]
public IActionResult Create()
{
return View();
}
[HttpPost("Create")]
public async Task<IActionResult> Create(CostItemViewModel model)
{
if (ModelState.IsValid)
{
var costItem = _mapper.Map<CostItem>(model);
await _unitOfWork.CostItems.AddAsync(costItem);
await _unitOfWork.SaveAsync();
return RedirectToAction(nameof(Index));
}
return View(model);
}
[HttpGet("Edit/{id}")]
public async Task<IActionResult> Edit(int id)
{
var costItem = await _unitOfWork.CostItems.GetByIdAsync(id);
if (costItem == null) return NotFound();
var model = _mapper.Map<CostItemViewModel>(costItem);
return View(model);
}
[HttpPost("Edit/{id}")]
public async Task<IActionResult> Edit(int id, CostItemViewModel model)
{
if (id != model.Id) return BadRequest();
if (ModelState.IsValid)
{
var costItem = _mapper.Map<CostItem>(model);
await _unitOfWork.CostItems.UpdateAsync(costItem);
await _unitOfWork.SaveAsync();
return RedirectToAction(nameof(Index));
}
return View(model);
}
[HttpGet("Delete/{id}")]
public async Task<IActionResult> Delete(int id)
{
var costItem = await _unitOfWork.CostItems.GetByIdAsync(id);
if (costItem == null) return NotFound();
var model = _mapper.Map<CostItemViewModel>(costItem);
return View(model);
}
[HttpPost("Delete/{id}")]
public async Task<IActionResult> DeleteConfirmed(int id)
{
await _unitOfWork.CostItems.DeleteAsync(id);
await _unitOfWork.SaveAsync();
return RedirectToAction(nameof(Index));
}
}
6. Представления
Теперь создадим представления для всех CRUD операций.
Index.cshtml
@model IEnumerable<CostItemViewModel>
<h1>Список затрат</h1>
<a asp-action="Create">Добавить новый элемент</a>
<table>
<thead>
<tr>
<th>Наименование затрат</th>
<th>Действия</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@item.CostName</td>
<td>
<a asp-action="Edit" asp-route-id="@item.Id">Редактировать</a>
<a asp-action="Delete" asp-route-id="@item.Id">Удалить</a>
</td>
</tr>
}
</tbody>
</table>
Create.cshtml
@model CostItemViewModel
<h1>Создать новый элемент</h1>
<form asp-action="Create">
<div>
<label>Наименование затрат</label>
<input asp-for="CostName" />
</div>
<div>
<label>Код узла ИСР</label>
<input asp-for="NodeCode" />
</div>
<!-- Добавьте остальные поля -->
<button type="submit">Создать</button>
</form>
Edit.cshtml
@model CostItemViewModel
<h1>Редактировать элемент</h1>
<form asp-action="Edit">
<input type="hidden" asp-for="Id" />
<div>
<label>Наименование затрат</label>
<input asp-for="CostName" />
</div>
<div>
<label>Код узла ИСР</label>
<input asp-for="NodeCode" />
</div>
<!-- Добавьте остальные поля -->
<button type="submit">Сохранить</button>
</form>
Delete.cshtml
@model CostItemViewModel
<h1>Удалить элемент</h1>
<p>Вы уверены, что хотите удалить элемент "@Model.CostName"?</p>
<form asp-action="DeleteConfirmed">
<input type="hidden" asp-for="Id" />
<button type="submit">Удалить</button>
<a asp-action="Index">Отмена</a>
</form>
7. Настройка AutoMapper
Не забудьте настроить AutoMapper в Startup.cs
или Program.cs
:
services.AddAutoMapper(typeof(Startup));
И создайте профиль для маппинга:
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<CostItem, CostItemViewModel>().ReverseMap();
}
}
Заключение
Теперь у вас есть базовая структура для CRUD операций с использованием ASP.NET Core 8 MVC, AutoMapper, паттернов Репозиторий и UnitOfWork. Вы можете расширять и модифицировать этот код в зависимости от ваших требований.