عملیات CRUD با AutoMapper در ASP.NET Core باعث سادهسازی و بهبود مدیریت دادهها بین مدلهای دیتابیس و ViewModelها میشود. AutoMapper فرآیند تبدیل (Mapping) بین مدلهای پیچیده و ساختارهای نمایش را خودکار میکند، بهطوری که دیگر نیازی به کدنویسی دستی برای انتقال دادهها نیست. این روش، علاوه بر کاهش پیچیدگی و افزایش خوانایی کد، خطر اشتباهات انسانی را در انتقال دادهها کاهش داده و عملکرد برنامه را در سطح بهتری مدیریت میکند.
قبل از هر کاری باید به فایل Mappings/MappingProfile.cs که در جلسه قبل ایجاد کردیم بریم. این کلاس برای مدیریت و تعریف Mapping ها ایجاد میشود تا پروژه شما ساختارمند، تمیز و انعطافپذیر باشد. در واقع توسط این کلاس ما AutoMapper را گانفیگ میکنیم.
public MappingProfile()
{
CreateMap<Manager,ManagerViewModel>();
CreateMap<Manager,ManagerFormViewModel>().ReverseMap();
//CreateMap<ManagerFormViewModel, Manager>();
}
تزریق AutoMapper به کنترلر باعث میشود که عملیات Mapping بهصورت خودکار و تمیز انجام شود. این کار موجب افزایش خوانایی، تستپذیری و نگهداری کد میشود.
private readonly MyDbContext _context;
private readonly IMapper _mapper;
public ManagersController(MyDbContext context,IMapper mapper)
{
_context = context;
_mapper = mapper;
}
روش اول : مپ به صورت ساده
var ManagerM = await _context.managers.ToListAsync();
List<ManagerViewModel> ManagerVm=_mapper.Map<List<ManagerViewModel>>(ManagerM);
روش دوم : مپ به صورت حرفه ای
var ManagerVm = await _context.managers.AsNoTracking().
ProjectTo<ManagerViewModel>(_mapper.ConfigurationProvider).ToListAsync();
if (ManagerVm.Count == 0)
{
ViewBag.Message = "مقداری یافت نشد";
}
return View(ManagerVm);
مند PopulateGenderList به شما امکان میدهد که به راحتی مقادیر ثابت همان Enum (مانند جنسیت) را در یک لیست انتخابی نمایش دهید، بدون اینکه نیاز باشد به صورت دستی مقادیر را وارد کنید. این موضوع کدنویسی را سادهتر و کمتر مستعد خطا میکند.
از این متد در اکشن های Create و Edit استفاده شده است.
private void PopulateGenderList()
{
ViewBag.GenderList = new SelectList(Enum.GetValues(typeof(Gender)).Cast<Gender>());
}
<select asp-for="Gender" asp-items="@ViewBag.GenderList" class="form-select"></select>
متد Details با استفاده از AutoMapper، دادههای جدول managers را به ViewModel تبدیل میکند. AutoMapper فرآیند Mapping را ساده کرده و کد را خواناتر میسازد. این متد نمونهای عالی از استفاده از AutoMapper برای کاهش پیچیدگی در تبدیل مدلها و بهبود خوانایی کد است.
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var ManagerVm = await _context.managers.
Where(a => a.Id == id).
ProjectTo<ManagerViewModel>(_mapper.ConfigurationProvider).
FirstOrDefaultAsync();
if (ManagerVm == null)
{
return NotFound();
}
return View(ManagerVm);
}
عملیات Create شامل متدهای GET و POST برای عملیات Create در ASP.NET Core است. با استفاده از AutoMapper، دادههای ورودی از ManagerFormViewModel به مدل Manager تبدیل شده و در دیتابیس ذخیره میشود. این فرآیند باعث سادهسازی Mapping و کاهش پیچیدگی کد میشود. اگر دادهها معتبر نباشند، دوباره View به همراه خطاهای معتبرسازی نمایش داده میشود.
public IActionResult Create()
{
PopulateGenderList();
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task Create([Bind("Id,Name,Family,Gender,Age")] ManagerFormViewModel ManagerVm)
{
if (ModelState.IsValid)
{
var ManagerM = _mapper.Map(ManagerVm);
ManagerM.RegisterDate = DateTime.Now;
//ManagerM.UserName = ManagerM.Name + "" + ManagerM.Family + "" + ManagerM.Id;
_context.Add(ManagerM);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
PopulateGenderList();
return View(ManagerVm);
}
عملیات Edit شامل متدهای GET و POST برای عملیات Edit در ASP.NET Core است. با استفاده از AutoMapper، دادههایدیتابیس به ManagerFormViewModel برای نمایش در فرم ویرایش تبدیل شده و پس از تغییرات کاربر دوباره به مدل Manager مپ میشود. و در دیتابیس ذخیره میشود. این فرآیند باعث سادهسازی Mapping و مدیریت بهتر دادهها در فرمهای ویرایش میشود. اگر خطا یا ناسازگاری رخ دهد، با پیام مناسب مدیریت میشود.
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var ManagerVm = await _context.managers
.Where(a=>a.Id==id)
.ProjectTo<ManagerFormViewModel>(_mapper.ConfigurationProvider)
.FirstOrDefaultAsync();
if (ManagerVm == null)
{
return NotFound();
}
PopulateGenderList();
return View(ManagerVm);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Name,Family,Gender,Age")] ManagerFormViewModel ManagerVm)
{
if (id != ManagerVm.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
var ManagerM = _mapper.Map<Manager>(ManagerVm);
_context.Update(ManagerM);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ManagerExists(ManagerVm.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
PopulateGenderList();
return View(ManagerVm);
}
عملیات Delete شامل متدهای GET و POST برای عملیات Delete در ASP.NET Core است. با استفاده از AutoMapper، اطلاعات مورد نظر از دیتابیس به ViewModel تبدیل شده و برای نمایش تأیید حذف به کاربر ارسال میشود. پس از تأیید کاربر، رکورد مربوطه از دیتابیس حذف شده و کاربر به صفحه اصلی هدایت میشود. این طراحی باعث مدیریت سادهتر عملیات حذف و جلوگیری از دسترسیهای غیرمجاز میشود.
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var ManagerVm = await _context.managers.
Where(a => a.Id == id).
ProjectTo<ManagerViewModel>(_mapper.ConfigurationProvider).
FirstOrDefaultAsync();
if (ManagerVm == null)
{
return NotFound();
}
return View(ManagerVm);
}
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var manager = await _context.managers.FindAsync(id);
if (manager != null)
{
_context.managers.Remove(manager);
}
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
استاد استفاده از auto mapper باعث کند شدن برنامه نمیشه؟ بعضی ها گفتن که باعث کند شدن میشود.