ASP.NET MVC , ORM and ViewModels
Since I am active on asp.net/mvc I find many peoples asking about
- One to many relationship .
- Dropdownlist
- How to use MVC with other ORM frameworks instead of Linq To Sql(L2S) ?
- What is a ViewModel and what is his purpose ?
For answering, I have made a small application with MVC2 in order to detail my answer.
First the problem :
You have Employees and Department.Each Employee belongs to an Department (let’s forget the fact that the employee can belong for a final date to the Department or any other life ideas)
The request is to create and view Employees .(forget delete,update – if I will have time and/or by general request , I will do this also this)
The database:
The beginning of the application :
First Layer , Data Access Layer
I use EF 3.5 (not 4.0 with POCO style – because is not ready yet) and make an edmx file and let EF put his classes.
You can use also ADO.NET with StoredProc, L2S, NHibernate or any other ORM you want.
Second Layer,Business Logic :
This is the layer where the logic should intervene (e.g., the name should be not null ).
Here is the list for Employee :
namespace BusinessLogic { /// <summary> /// TODO : add IDataErroInfo in order to validate /// TODO : add the department /// </summary> public class Employee { public long ID; public string Name { get; set; } public Department Department{ get; set; } public void SaveNew() { //TODO : validate before save //TODO : automapper using (DAL_EF.testsEntities te = new DAL_EF.testsEntities("name=myconnection")) { DAL_EF.Employee e = new DAL_EF.Employee(); e.Name = this.Name; //TODO : what if dept. deleted ? e.Department =te.Department.Where(d=>d.ID== this.Department.ID).FirstOrDefault(); te.AddToEmployee(e); te.SaveChanges(); } } } public class EmployeeList : List<Employee > { public void Load() { using (DAL_EF.testsEntities te = new DAL_EF.testsEntities("name=myconnection")) { foreach (var emp in te.Employee.Include("Department")) { //TODO : use automapper Employee e=new Employee() { ID = emp.ID, Name = emp.Name }; e.Department=new Department(){ ID=emp.Department.ID,Name=emp.Department.Name}; this.Add(e); } } } } }
Please pay attention for Load procedure in EmployeeList : it uses the first layer, DAL, but it can use any ORM framework.
Third layer, ViewModel:
Because all the views for employees will need a select list for department ( either for sorting, creating or updating) I have put a base ViewModel class that retrieves the list of Departments:
namespace MVCAppEmp.Classes { public class ViewModelEmployee { public static SelectList ListOfDepartments { get { //TODO : put this into cache to not load every time DepartmentList dl = new DepartmentList(); dl.Load(); return dl.SelectFromList(x => x.ID.ToString(), y => y.Name); } } } public class ViewModelEmployeeCreate : ViewModelEmployee { public Employee emp=new Employee(); } public class ViewModelEmployeeList : ViewModelEmployee { public EmployeeList employees; public void Load() { employees = new EmployeeList(); employees.Load(); } } }
Fourth Layer , MVC itself – view and controller :
<% =Html.ValidationSummary() %> <% using (Html.BeginForm()) { %> <h2>Create</h2> List of departments : <% =Html.DropDownList("DepartmentID", MVCAppEmp.Classes.ViewModelEmployee.ListOfDepartments)%> <%=Html.EditorFor(model => model.emp)%> <input type="submit" value="create" /> <%} %>
and the controller
// POST: /Employee/Create // TODO: make a binding for employees [HttpPost] public ActionResult Create(Employee emp,long DepartmentID) { try { emp.Department = new Department() { ID = DepartmentID }; emp.SaveNew(); return RedirectToAction("Index"); } catch(Exception ex) { ModelState.AddModelError("", ex.Message); return View(new ViewModelEmployeeCreate(){emp=emp}); } }
So to answer the questions :
- One to many relationship – easy to do, most difficult to program
- Dropdownlist – easy – just transform a list into a select list, provided you have all data belongs
- How to use MVC with other ORM frameworks instead of Linq To Sql(L2S) ? Does not matter ! Just create your BusinessLogic and use that ORM!
- What is a ViewModel and what is his purpose ? To fill the data for GUI that BusinessLogic does not comply and transfer data to BusinessLogic. Reciprocally too!
You will find attached the application and the sql to create the database :
For MVC2 /MVC 3
http://msprogrammer.serviciipeweb.ro/wp-content/uploads/ASP.NETMVCORMandViewModels_135E/emp.zip
For MVC 4
http://msprogrammer.serviciipeweb.ro/wp-content/uploads/ASP.NETMVCORMandViewModels_135E/empMVC4.zip
What to do next, in order to familiarize yourself :
1. Make the update of the employees .Create view, save.
2. Filter the list of the employees on department. Search for all employees beginning with A that belong to IT department.
3. Search for TODO’s : there are part of other tutorials – but it will help you in MVC (and other!) development
This post have a continuation here:
http://msprogrammer.serviciipeweb.ro/2010/07/05/asp-net-mvc-and-dos-re-using-the-viewmodels/
Hi, Great blog by the way. I’m working with MVC 2 and EF 4 with POCO. For some reason I’m getting this error message: Mapping and metadata information could not be found for EntityType ‘NorthwindMvcPoco.Models.Category’.
I upload my project in Rapidshare: http://rapidshare.com/files/372303498/NorthwindMvcPoco.rar.html
Please check out the project and help me out. I use VS 2010 and SQL Server 2008. I’m using Northwind as my database.
Please post your problem on MVC
http://forums.asp.net/1146.aspx
or read
http://msprogrammer.serviciipeweb.ro/aspnet-mvc-tips-and-tricks/
Really useful information – simple example of the different layers in an MVC project. The way you store your business logic in a custom class is the way that I have been doing things too and it’s good to know that I’m on the right track – thanks for your response to http://forums.asp.net/p/1758603/4779940.aspx/1?Re+Class+design+101
Can u please tell me, where we use model view and view model? what ia the difference between them?
Thanks
Usually, Model is database Model ( mapping table in code)
ViewModel is the Model of the View – see example in this post.
Hi,
I was trying understand your code here. I have one issue;
In layer 3 line 10, where is the DepartmentList class? What is inside it?
public static SelectList ListOfDepartments
{
get
{
//TODO : put this into cache to not load every time
DepartmentList dl = new DepartmentList(); x.ID.ToString(), y => y.Name);
}
Also, can you suggest me best way to show dropdownlist based on foreign key in Razor?
Thanks,
Deepak.
First off, good article. We have been arguing to do the same thing (because we are making a transition from C#.NET desktop to web ASP.NET MVC).
Our question is, how do you support automatic paging/sorting this way via EF?
Search for Troy Goode Paging
Hi Andrei, great article.
Could you provide the example forVisual Studio 2012, The MCV project is reporting incompatible.
Best Regards
Hélder
Update with VS2012, MVC4
Provided
Hi,
In the business logic layer I can see that using (DAL_EF.testsEntities te = new DAL_EF.testsEntities(“name=myconnection”)). I am planning to make the DLL of the business logic layer and use it in the UI. How will you pass “myconnection” which is in the web.config to the busieness logic layer via DLL?
Thanks,
Paul
via a new property – or parameter to the function
how to make communication b/w model and controller while using ADO.net code in our model…?
The Model of the View can call various ADO.NET functions.