实体框架类与POCO [英] Entity Framework classes vs. POCO

查看:103
本文介绍了实体框架类与POCO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对建筑设计有一个普遍的意见差异,尽管不应该使用stackoverflow来提出意见,我想要求两种方法的利弊:我将在下面描述:



详细信息:
- C#应用程序
- SQL Server数据库
- 使用实体框架
- 我们需要决定我们要做什么对象用于存储我们的信息并在整个应用程序中使用所有内容



场景1:
我们将使用实体框架实体传递我们的应用程序,例如该对象应用于存储所有信息,我们将其传递给BL,最终我们的WepApi将使用该实体并返回值。没有DTO和POCO。



如果数据库模式发生变化,我们会更新实体并修改所有使用该类的实体。



方案2:
我们创建一个中间类 - 将其称为DTO或将其称为POCO - 以容纳应用程序所需的所有信息。有一个中间步骤,将存储在实体中的信息填充到POCO中,但是我们将所有EF代码保存在数据访问中,而不是跨所有层。



什么是每个人的利弊?

解决方案

我将使用中间类,即POCO而不是EF实体。 >

我直接使用EF实体的唯一优点是编写代码较少...



使用优点POCO:



您只公开您的应用程序实际需要的数据



基本上说,你有一些 GetUsers 业务方法。如果您只想让用户列表填充网格(例如,您需要其ID,名称,名字,例如),您可以这样写:

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

清晰的方法实际返回。
现在想象一下,它返回一个完整的用户实体,其中包含您不想公开的所有导航属性和内部内容(例如密码字段)...



它真的简化了消费您的服务的人的工作



对于创建,像业务方法更为明显。您当然不想使用用户实体作为参数,对于您的服务的消费者来说,知道属性是非常复杂的实际需要...



想象一下下列实体:

  public用户类
{
public long ID {get;组; }
public string Name {get;组; }
public string FirstName {get;组; }
public string Password {get;组; }
public bool IsDeleted {get;组; }
public bool IsActive {get;组; }
public virtual ICollection< Profile>个人资料{get;组; }
public virtual ICollection< UserEvent>活动{get;组; }
}

您需要使用哪些属性才能使用 void Create(User entity); 方法




  • ID:dunno,也许它的生成可能不是

  • 名称/名字:那些应该设置

  • 密码:是纯文本密码,散列版本?是什么?

  • IsDeleted / IsActive:我应该自己激活用户吗?是否通过业务方式完成?

  • 个人资料:嗡嗡声...如何影响用户的个人资料?

  • 活动:地狱是



它强制你不要使用懒惰加载



是的,我憎恶此功能有多个原因。其中一些是:




  • 非常难以有效地使用。我看过太多次代码,产生了数千个SQL请求,因为开发人员不知道如何正确使用延迟加载

  • 非常难以管理异常。通过允许在任何时间执行SQL请求(即,当您进行延迟加载时),您将管理数据库异常的角色委托给上层,即业务层甚至应用程序。一个不好的习惯。



使用POCO强制您急于加载您的实体,更好的IMO。



关于AutoMapper



AutoMapper 是一种允许您将实体自动转换为POCO的工具,反之亦然。我也不喜欢它。请参阅 https://stackoverflow.com/a/32459232/870604


I have a general difference of opinion on an architectural design and even though stackoverflow should not be used to ask for opinions I would like to ask for pros and cons of both approaches that I will describe below:

Details: - C# application - SQL Server database - Using Entity Framework - And we need to decide what objects we are going to use to store our information and use all throughout the application

Scenario 1: We will use the Entity Framework entities to pass all around through our application, for example the object should be used to store all information, we pass it around to the BL and eventually our WepApi will take this entity and return the value. No DTOs nor POCOs.

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

Scenario 2: We create an intermediate class - call it a DTO or call it a POCO - to hold all information that is required by the application. There is an intermediate step of taking the information stored in the entity and populated into the POCO but we keep all EF code within the data access and not across all layers.

What are the pros and cons of each one?

解决方案

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

这篇关于实体框架类与POCO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆