The approach you choose depends on the type of project you are going to work with. For small projects that require the Rapid Application Development ( RAD ) approach, it can be almost normal to use your EF model directly in the MVC project and have access to the data in the controllers, but the larger the project, the more dirty it will become, and you will start to face more and more new problems. If you need good design and maintainability, there are several different approaches, but in general you can stick to the following:
Keep your controllers and views clean. Controllers should control the flow of applications, and not contain access to data or even business logic. Views should be used only for presentation - provide it with a ViewModel and present it as Html (without business logic or calculations). A ViewModel for presentation is a pretty clean way to do this.
A typical controller action would look like this:
public ActionResult UpdateCompany(CompanyViewModel model) { if (ModelState.IsValid) { Company company = SomeCompanyViewModelHelper. MapCompanyViewModelToDomainObject(model); companyService.UpdateCompany(company); return RedirectToRoute(/* Wherever you go after company is updated */); } // Return the same view with highlighted errors return View(model); }
Due to the aforementioned reasons, itโs good to abstract data access (testability, ease of switching the data provider or ORM, or something else, etc.). The Repository template is a good choice, but here you also get several implementation options. There has always been a lot of discussion about generic / non-generic repositories, whether IQueryable s should be returned, etc. But ultimately it's up to you to choose.
By the way, why do you want lazy loading? As a rule, you know exactly what data you need for a certain type, so why did you decide to retrieve it in a deferred way, thereby making additional database calls, instead of loading everything you need in one call? Personally, I believe that everything is in order to have several Get methods for retrieving objects with or without children. For example.
public class CompanyRepository { Get(int Id); Get(string name); GetWithEmployees(int id); ... }
This may seem a bit picky, and you can choose a different approach, but as long as you have a template that suits you, maintaining the code is much easier.