I’ve been trying to debate on how to add information on a table with child tables. When I initialize a User, the user needs to have the password encrypted and the data inserted into the child classes. As I am not fully familiar with the Repository, Unit of Work Patterns, I want to ensure I do this properly the first time around. Thanks!
My tables are:
User, UserRoles
My Code:
[HttpPost]
public ActionResult AddUser(User user)
{
try
{
if (ModelState.IsValid)
{
uow.UserRepository.Insert(user);
uow.Save();
return RedirectToAction("Index", "User");
}
}
catch (DataException)
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
return View(user);
}
public class UserRepository : IUserRepository, IDisposable
{
private StudentSchedulingEntities _context;
public UserRepository(StudentSchedulingEntities context)
{
if (context == null)
throw new ArgumentNullException("context");
_context = context;
}
public IEnumerable<User> GetUsers()
{
return _context.Users.ToList();
}
public User GetUserByID(int id)
{
return _context.Users.Find(id);
}
public void InsertStudent(User user)
{
_context.Users.Add(user);
}
public void DeleteStudent(int userID)
{
User usr = _context.Users.Find(userID);
_context.Users.Remove(usr);
}
public void UpdateStudent(User user)
{
_context.Entry(user).State = EntityState.Modified;
}
public void Save() {
_context.SaveChanges();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
}
public interface IUserRepository : IDisposable
{
IEnumerable<User> GetUsers();
User GetUserByID(int userID);
void InsertStudent(User user);
void DeleteStudent(int userID);
void UpdateStudent(User user);
void Save();
}
public class UnitOfWork : IDisposable
{
private StudentSchedulingEntities _context = new StudentSchedulingEntities();
private GenericRepository<User> userRepository;
public GenericRepository<User> UserRepository
{
get
{
if (this.userRepository == null)
{
this.userRepository = new GenericRepository<User>(_context);
}
return userRepository;
}
}
public void Save()
{
_context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
Update From Comments:
[HttpPost]
public ActionResult AddUser(AddUserViewModel auvm)
{
try
{
if (ModelState.IsValid)
{
uow.UserRoleRepository.Insert(auvm.UserRole);
uow.UserRepository.Insert(auvm.User);
uow.Save();
return RedirectToAction("Index", "User");
}
}
catch (DataException)
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
return View(auvm);
}
public class AddUserViewModel
{
public User User { get; set; }
public UserRole UserRole { get; set; }
public UserRoleType UserRoleType { get; set; }
public IEnumerable<SelectListItem> UserRoleTypes { get; set; }
}
Simply create a new User object. Assign the UserRoles to the user. Save the user object. The context class acts as the unit of work – it saves everything only when you call Save Changes.
Your code above seems to be doing this except for the roles, so far it seems OK to me.
Some choose to go the ViewModel route (which is recommended) so you would be posting a UserCreateViewModel which looks very similar to your User class. This way if the user class changes or you don’t want everything exposed to the user, you can more easily handle these cases.