Entity Framework classes vs. POCO

*爱你&永不变心* 提交于 2019-12-04 05:36:40
ken2k

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

The only advantage I see to directly use EF entities is that it's less code to write...

Advantages to use POCO instead:

You only expose the data your application actually needs

Basically, say you have some GetUsers business method. If you just want the list of users to populate a grid (i.e. you need their ID, name, first name for example), you could just write something like that:

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

It is crystal clear what your method actually returns. Now imagine instead, it returned a full User entity with all the navigation properties and internal stuff you do not want to expose (such as the Password field)...

It really simplify the job of the person that consumes your services

It's even more obvious for Create like business methods. You certainly don't want to use a User entity as parameter, it would be awfully complicated for the consumers of your service to know what properties are actually required...

Imagine the following entity:

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; }
}

Which properties are required for you to consume the void Create(User entity); method?

  • ID: dunno, maybe it's generated maybe it's not
  • Name/FirstName: well those should be set
  • Password: is that a plain-text password, an hashed version? what is it?
  • IsDeleted/IsActive: should I activate the user myself? Is is done by the business method?
  • Profiles: hum... how do I affect a profile to a user?
  • Events: the hell is that??

It forces you to not use lazy loading

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

  • extremely hard to use efficiently. I've seen too much times code that produces thousands of SQL request because the developers didn't know how to properly use lazy loading
  • extremely hard to manage exceptions. By allowing SQL requests to be executed at any time (i.e. when you lazy load), you delegate the role of managing database exceptions to the upper layer, i.e. the business layer or even the application. A bad habit.

Using POCO forces you to eager-load your entities, much better IMO.

About AutoMapper

AutoMapper is a tool that allows you to automagically convert Entities to POCOs and vice et versa. I do not like it either. See https://stackoverflow.com/a/32459232/870604

I have a counter-question: Why not both?

Consider any arbitrary MVC application. In the model and controller layer you'll generally want to use the EF objects. If you defined them using Code First, you've essentially defined how they are used in your application first and then designed your persistence layer to accurately save the changes you need in your application.

Now consider serving these objects to the View layer. The views may or may not reflect your objects, or an aggregation of your working objects. This often leads to POCOS/DTO's that captures whatever is needed in the view. Another scenario is when you want to publish objects in a web service. Many frameworks provide easy serialization on poco classes in which case you typically either need to 1) annotate your EF classes or 2) make DTO's.

Also be aware that any lazy loading you may have on your EF classes is lost when you use POCOS or if you close your context.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!