Entity Framework Classes vs. POCO

I have a general difference of opinion on architectural design, and although stackoverflow should not be used to request opinions, I would like to ask for and against both approaches, which I will describe below:

More details: - C # application - SQL Server database - Using Entity Framework - And we need to decide which objects we will use to store our information and use everything in the application

Scenario 1: We will use Entity Framework entities to traverse our entire application, for example, an object should be used to store all information, we pass it BL and, ultimately, our WepApi will take this object and return a value. No DTO and POCOs.

If the database schema changes, we update the object and change it in all classes where it is used.

Scenario 2: We create an intermediate class - call it DTO or call it POCO - to store all the information required by the application. There is an intermediate step for storing information stored in the entity and filled in POCO, but we save all the EF code inside the data access, and not through all layers.

What are the pros and cons of each?

+5
source share
2 answers

I would use intermediate classes, i.e. POCO instead of EF objects.

The only advantage I see for directly using EF objects is that it is smaller than the code to write ...

Benefits of using POCO:

You publish only the data that your application really needs

Basically, let's say you have a GetUsers business method. If you just want the list of users to fill the grid (i.e. you need their identifier, name, name, for example), you can simply write something like this:

 public IEnumerable<SimpleUser> GetUsers() { return this.DbContext .Users .Select(z => new SimpleUser { ID = z.ID, Name = z.Name, FirstName = z.FirstName }) .ToList(); } 

Clearly, your method is indeed returning. Now imagine that he returned a complete User object with all the navigation properties and internal things that you do not want to reveal (for example, the Password field) ...

It really simplifies the work of the person who consumes your services

This is even more obvious for Create as business methods. Of course, you don’t want to use the User object as a parameter, it would be terribly difficult for consumers of your service to find out what properties are really necessary ...

Imagine the following object:

 public class User { public long ID { get; set; } public string Name { get; set; } public string FirstName { get; set; } public string Password { get; set; } public bool IsDeleted { get; set; } public bool IsActive { get; set; } public virtual ICollection<Profile> Profiles { get; set; } public virtual ICollection<UserEvent> Events { get; set; } } 

What properties are needed to use the void Create(User entity); method void Create(User entity); ?

  • ID: dunno, maybe it's generated, maybe it's not
  • Name / FirstName: well, they must be installed
  • Password: is it a plain text password, hashed version? what is it?
  • IsDeleted / IsActive: Should I activate the user myself? Is this done by a business method?
  • Profiles: buzz ... how to influence the profile for the user?
  • Events: what the hell ??

It forces you to not use lazy loading

Yes, I hate this feature for several reasons. Some of them:

  • extremely difficult to use effectively. I have seen too much code that produces thousands of SQL queries because the developers did not know how to use lazy loading correctly.
  • it is extremely difficult to manage exceptions. By allowing SQL queries to be executed at any time (for example, during lazy loading), you delegate the role of database exception management to the upper level, that is, to the business layer or even to the application. Bad habit.

Using POCO makes you load your objects, much better than IMO.

About AutoMapper

AutoMapper is a tool that allows you to automatically convert objects to POCOs and vice versa. I do not like it either. See fooobar.com/questions/1234708 / ...

+4
source

I have a counter question: why not get around?

Consider any arbitrary MVC application. At the model and controller level, you usually want to use EF objects. If you defined them using Code First, you basically determined how they are used in your application, and then designed your persistence level to accurately save the changes needed in your application.

Now consider the possibility of servicing these objects at the presentation level. Views may or may not reflect your objects or the aggregation of your work objects. This often leads to POCOS / DTO, which captures everything that is needed in the view. Another scenario is when you want to publish objects to a web service. Many frameworks provide easy serialization on poco classes, in which case you usually need to: 1) annotate your EF classes or 2) make a DTO.

Also keep in mind that any lazy loading you may have on your EF classes is lost when you use POCOS or close your context.

+4
source

Source: https://habr.com/ru/post/1234699/


All Articles