Practical way for separate Entity classses (DTO) from EDMX

1.2k Views Asked by At

I have a 3-tiered application

DAL has EDMX file that EF6 generated it automatically from database (DB First mode). I have BLL and UL layers too.

But, when I want to use BLL methods in UI, I must add DAL assembly to UI layer (because of return types of methods)

List<Person> 

Person define in EDMX (DAL)] (this my problem)

How I can separate classes (DTO) from EDMX file and create as separate assembly?

How can I prevent adding DAL Assembly (whole EDMX) to the UI layer?

3

There are 3 best solutions below

3
On

Good question, the accepted wisdom is that you define a different Person for each tier/layer (DAL, BLL and UI) and then write code to map between each layer. There's AutoMapper which can make life easier.

Now consider a real-life application with 100 to 1,000 entities. This pattern does not scale well.

I suggest using the Code First approach to EF. And passing the same object between all your layers.

0
On

Just move the TT files for the POCOs to a different project and leave the EDMX TT files in the DAL. That way you have essentially DTOs/POCO in their own model project, and that can be referenced wherever it is needed.

1
On

Here is what I would do. To decouple the DAL from the UI, you will need a "middle tier". Consider the following diagram.

enter image description here

The middle tier is widely know as the service layer or the application layer.

Everytime the Person data passes from one layer to another, it is "mapped" to its equivalent class for that specific layer.

The following snippets makes up the very basic example of a service layer. I did not include the other details such as AutoMappers and other general practices.

The PersonDto, defined in the middle tier, represents the Person entity.

public class PersonDto
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

The PersonService class. It encapsulates the data access and business logic, and returns only the PersonDto (instead of the entities). It is how the UI communicates with the domain.

public class PersonService
{
    public PersonDto GetPersonById(int id)
    {
         Person person = dbContext.Persons.Find(id);
         
         // Mapping in action.
         var personDto = new PersonDto()
         {
             FirstName = person.FirstName,
             LastName = person.LastName,
         };

         return personDto;
    }
}

This PersonService is what the UI code sees, it does not know about the data access or the business logic. It only knows about the services.

The services should encapsulate your business logic, decoupling the UI from the BLL and DAL.