Should be quite simple in .NET core MVC
public interface IAuthorsDataRepository
{
Task Create(AuthorViewModel author);
Task<AuthorViewModel> GetDetails(int id);
DbSet<AuthorViewModel> GetAll();
Task<AuthorViewModel?> GetNotTracking(int id);
Task Edit(AuthorViewModel author);
Task Delete(int id);
}
your repo:
public class AuthorstDataRepository : IAuthorsDataRepository
{
private readonly BooksManagementSystemContext _context;
public AuthorstDataRepository(BooksManagementSystemContext context)
{
this._context = context;
}
public async Task Create(AuthorViewModel author)
{
_context.Add(author);
await _context.SaveChangesAsync();
}
public async Task Delete(int id)
{
var authorToDelete = new AuthorViewModel() { Id = id };
_context.Entry(authorToDelete).State = EntityState.Deleted;
await _context.SaveChangesAsync();
}
public async Task Edit(AuthorViewModel author)
{
_context.Update(author);
await _context.SaveChangesAsync();
}
public DbSet<AuthorViewModel> GetAll()
{
return _context.Authors;
}
public async Task<AuthorViewModel> GetDetails(int id)
{
return await _context.Authors.FindAsync(id);
}
public async Task<AuthorViewModel?> GetNotTracking(int id)
{
return await _context.Authors
.AsNoTracking()// EF extension to update existing user instead of inserting a new one
.FirstOrDefaultAsync(m => m.Id == id);
}
}
Usage in the controller:
public class AuthorController : Controller
{
private readonly IAuthorsDataRepository _repository;
public AuthorController(IAuthorsDataRepository repository)
{
this._repository = repository;
}
// GET: AuthorController
[Authorize(Roles = "Admin")]
public ActionResult Index()
{
return View(_repository.GetAll());
}
// GET: AuthorController/Details/5
[Authorize(Roles = "Admin")]
public async Task<IActionResult> Details(int id)
{
var author = await _repository.GetDetails(id);
if (author == null)
{
return NotFound();
}
return View(author);
}
// GET: AuthorController/Create
public ActionResult Create()
{
return View();
}
// POST: AuthorController/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,AuthorFirstname,AuthorSecondname")]
AuthorViewModel author)
{
try
{
if (ModelState.IsValid)
{
await _repository.Create(author);
return RedirectToAction(nameof(Index));
}
}
catch (DbUpdateException ex)
{
//Log the error (uncomment ex variable name and write a log.
ModelState.AddModelError("", "Unable to save changes. " +
"posible reason is " + ex.Message);
}
return View(author);
}
// GET: AuthorController/Edit/5
public async Task<IActionResult> Edit(int id)
{
var author = await _repository.GetNotTracking(id);
if (id != author.Id)
{
return NotFound();
}
if (author == null)
{
return NotFound();
}
return View(author);
}
// POST: AuthorController/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,AuthorFirstname,AuthorSecondname")]
AuthorViewModel author)
{
if (id != author.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
await _repository.Edit(author);
return RedirectToAction(nameof(Index));
}
catch (DbUpdateException ex)
{
//Log the error (uncomment ex variable name and write a log.
ModelState.AddModelError("", "Unable to save changes. " +
"posible reason is " + ex.Message);
}
}
return View(author);
}
// GET: AuthorController/Delete/5
public async Task<IActionResult> Delete(int? id, bool? saveChangesError = false)
{
if (id == null)
{
return NotFound();
}
var author = await _repository.GetNotTracking(id.GetValueOrDefault());
if (author == null)
{
return NotFound();
}
if (saveChangesError.GetValueOrDefault())
{
ViewData["ErrorMessage"] =
"Delete failed. Try again, and if the problem persists " +
"see your system administrator.";
}
return View(author);
}
// POST: AuthorController/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
try
{
await _repository.Delete(id);
return RedirectToAction(nameof(Index));
}
catch (DbUpdateException /* ex */)
{
//Log the error (uncomment ex variable name and write a log.)
return RedirectToAction(nameof(Delete), new { id = id, saveChangesError = true });
}
}
}
and the connection between your class in the interface in the program class:
builder.Services.AddScoped<IAuthorsDataRepository, AuthorstDataRepository>();
One note: AddSingleton does not work with the data context.