Search code examples
asp.net-mvcarchitecturen-tier-architecture

Mapping Entities to Models and Performing Business Logic in ASP.NET MVC


What is the best practise in mapping your database entities to your models and performing business logic? I've seen considerably different implementations of both. I have noticed a number of implementations where the Repository(in the Data Layer) itself is responsible for mapping the database entities to the domain models. For example, a repository that would do this:

public IQueryable<Person> GetPersons()
{
      return DbSet.Select(s => new Person
                    {
                        Id = s.Id,
                        FirstName= s.FirstName,
                        Surname= s.Surname,
                        Location = s.Location,
                    });
}

But having searched comprehensively around SO on N Tier design, I've noticed that while there is no silver bullet, in most situations it's advisable to perform the mapping inside the controller in the MVC project either manually or using a Mapper. It's also been reiterated that the Service layer should never perform the mapping and that it's responsibility should be to perform business logic. A couple of questions here:

  1. Which method is advisable in regards to where to map the entities to models and vice versa? Should the repository do this or should the mapping be done in the controller?
  2. Suppose I want to perform some business logic on the entities that I have retrieved from the database, for example, return the full name of the Person enities, or increase the age of all Persons by 10 years, where should this operation be performed. On the model itself? For example would I have a FullName property on the model which would compute the full name and the age? Or do I define some service inside my service layer to perform business logic?

EDIT

Wow so many close votes. Apologies, I didn't search comprehensively enough. The 'where to perform business logic' issue I've raised here can already be found on SO and elsewhere (although conveyed somewhat cryptically at times):

Validating with a Service Layer by Stephen Walther

Skinny Controllers

Another great, but more generic answer here on SO

Where Should I put My Controller Business Logic in MVC

Does a Service Map Entities to a View Model

However I'm yet to find a standard solution to the mapping question I had, and I think I could have perhaps expressed my question more eloquently. So the general consensus seems to be that business logic goes in the service layer, and mapping the domain models to view models should take place in the controller/presentation layer. And since it's advisable not to surface your DB entities to any layers other than the Data layer, it's recommended to map your entities to domain models at the data layer either manually or via a mapper such as Auto Mapper (This is what I have gathered from reading many articles). My confusion arose from the question of where should mapping entities to domain models and mapping domain models to view models take place. However as I previously alluded to I could have expressed my question more clearly. The reason for my confusion was that I had read that mapping entities to to domain models should happen in the controller, this should rather be rephrased to say "Mapping entities to domain models should happen at the data later, and mapping domain models to view models should take place in the Controller.


Solution

    1. Which method is advisable in regards to where to map the entities to models and vice versa? Should the repository do this or should the mapping be done in the controller?

    I strongly prefer to see the mapping happen in the repository and not the controller. The controller needs to act purely as a coordinator as Suhas mentions in his answer. As an alternative, maybe you can utilize a mapping class in the repository that passes the entity and return a mapped model - kind of like Auto Mapper

    1. Suppose I want to perform some business logic on the entities that I have retrieved from the database, for example, return the full name of the Person enities, or increase the age of all Persons by 10 years, where should this operation be performed. On the model itself? For example would I have a FullName property on the model which would compute the full name and the age? Or do I define some service inside my service layer to perform business logic?

    If it's possible, perform the business logic on the service. Why put the burden on the application to do what the service layer should have done? I believe this is the service's domain, not the app's. Also, I don't think returning concatenated or derived properities from the model is a bad thing either.

    Summary:

    • Controller handles requests from views and forwards them to repository
    • Repository is the conduit to your datastores
    • Service handles requests from repository, processes business logic, and returns mapped models