Right now, in smaller projects, I flounder between 3 approaches. I would like to choose one of them to use consistently.
I have put example code, with pros/cons below. But essentially, the 3 approaches boil down to:
- All DB work in controller
- DB instance passed from controller into ViewModel, and work done there
- DB created in ViewModel with (using), and work done there
Why would an experienced developer choose one approach over another?
Are there any benefits / disadvantages to these approaches that - as a beginner - I might not be aware of?
Update
I appreciate that these patterns may not be used in larger projects which tend to me more structurally complex.
But really I am interested in the difference in them when they ARE used.
Approach One
All DB work and vaildation flow in controller
Makes it easy to grasp what's going on for simple applications...
...but 'fat' controllers may obscure understanding for complex applications.
Default used by MS in MVC template
public class ModelOne
{
public int ID { get; set; }
public string PropA { get; set; }
public string PropB { get; set; }
public string PropC { get; set; }
// etc...
}
public class EditModelOnePropAViewModel
{
public EditModelOnePropAViewModel(ModelOne model)
{
ID = model.ID;
PropA = model.PropA;
}
public string PropA { get; set; }
public int ID { get; set; }
}
public class ControllerOne : Controller
{
private ApplicationDbContext DB = new ApplicationDbContext() { };
[HttpGet]
public ActionResult Edit(int id)
{
var model = DB.ModelOneDbSet.FirstOrDefault(i => i.ID);
var viewModel = new EditModelOnePropAViewModel(model);
return View(viewModel);
}
[HttpPost]
public ActionResult Edit(EditModelOnePropAViewModel postedModel)
{
if (ModelState.IsValid)
{
var model = DB.ModelOneDbSet.FirstOrDefault(i = i.ID == postedModel.ID);
model.PropA = postedModel.PropA;
DB.SaveChanges();
return RedirectToAction("index");
}
return View(postedModel);
}
}
Approach Two
DB passed into ViewModel from Controller
Controller is 'thin' and 'dumb'.
Because we are using the controller's DB instance, it's Dispose() method will be called on the DB object.
public class ModelTwo
{
public int ID { get; set; }
public string PropA { get; set; }
public string PropB { get; set; }
public string PropC { get; set; }
// etc...
}
public class EditModelTwoPropAViewModel
{
public EditModelTwoPropAViewModel(ApplicationDbContext db, int id)
{
ID = id;
PropA = db.ModelTwoDbSet
.Where(i => i.ID == id)
.Select(i => i.PropA)
.FirstOrDefault();
}
public void SaveChanges(ApplicationDbContext db)
{
var modelTwo = db.ModelTwoDbSet.FirstOrDefault(i => i.ID == ID);
modelTwo.PropA = PropA;
db.SaveChanges();
}
public string PropA { get; set; }
public int ID { get; set; }
}
public class ControllerTwo : Controller
{
private ApplicationDbContext DB = new ApplicationDbContext() { };
[HttpGet]
public ActionResult Edit(int id)
{
var viewModel = new EditModelTwoPropAViewModel(DB, id);
return View(viewModel);
}
[HttpPost]
public ActionResult Edit(EditModelTwoPropAViewModel postedModel)
{
if (ModelState.IsValid)
{
postedModel.SaveChanges(DB);
return RedirectToAction("index");
}
return View(postedModel);
}
}
Approach Three
Same as Two, but DB created with (using) in ViewModel.
public class ModelThree
{
public int ID { get; set; }
public string PropA { get; set; }
public string PropB { get; set; }
public string PropC { get; set; }
// etc...
}
public class EditModelThreePropAViewModel
{
public EditModelThreePropAViewModel(int id)
{
using (var db = new ApplicationDbContext())
{
ID = id;
PropA = db.ModelThreeDbSet
.Where(i => i.ID == id)
.Select(i => i.PropA)
.FirstOrDefault();
}
}
public void SaveChanges()
{
using (var db = new ApplicationDbContext())
{
var modelThree = db.ModelThreeDbSet.FirstOrDefault(i => i.ID == ID);
modelThree.PropA = PropA;
db.SaveChanges();
}
}
public string PropA { get; set; }
public int ID { get; set; }
}
public class ControllerThree : Controller
{
[HttpGet]
public ActionResult Edit(int id)
{
var viewModel = new EditModelThreePropAViewModel(id);
return View(viewModel);
}
[HttpPost]
public ActionResult Edit(EditModelThreePropAViewModel postedModel)
{
if (ModelState.IsValid)
{
postedModel.SaveChanges();
return RedirectToAction("index");
}
return View(postedModel);
}
}