实体框架类与POCO

时间:2015-10-28 13:25:51

标签: c# entity-framework architecture poco

我对建筑设计有一般意见分歧,尽管不应该使用stackoverflow来征求意见,我想问两种方法的优缺点,我将在下面介绍:

详细说明: - C#应用程序 - SQL Server数据库 - 使用实体框架 - 我们需要确定我们将使用哪些对象来存储我们的信息并在整个应用程序中使用所有对象

场景1: 我们将使用Entity Framework实体来遍历我们的应用程序,例如,该对象应该用于存储所有信息,我们将它传递给BL,最终我们的WepApi将获取此实体并返回值。没有DTO或POCO。

如果数据库架构发生更改,我们会更新实体并在所有使用它的类中进行修改。

场景2: 我们创建一个中间类 - 称之为DTO或称之为POCO - 以保存应用程序所需的所有信息。有一个中间步骤,即获取存储在实体中的信息并填充到POCO中,但我们将所有EF代码保留在数据访问中,而不是所有层中。

每个人的利弊是什么?

2 个答案:

答案 0 :(得分:4)

我有一个反问题:为什么不两者?

考虑任何任意MVC应用程序。在模型和控制器层中,您通常希望使用EF对象。如果您使用Code First定义它们,那么您基本上已经定义了它们在应用程序中的使用方式,然后设计了持久层以准确保存应用程序中所需的更改。

现在考虑将这些对象提供给View层。视图可能反映您的对象,也可能不反映您的工作对象的聚合。这通常会导致POCOS / DTO捕获视图中所需的任何内容。另一种情况是您希望在Web服务中发布对象。许多框架提供了对poco类的简单序列化,在这种情况下,您通常需要1)注释您的EF类或2)制作DTO。

另请注意,当您使用POCOS或关闭上下文时,您在EF课程上可能出现的任何延迟加载都会丢失。

答案 1 :(得分:4)

我会使用中间类,即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();
}

很清楚你的方法实际返回的是什么。 现在想象一下,它返回了一个完整的User实体,其中包含您不想公开的所有导航属性和内部内容(例如Password字段)......

它确实简化了消费者服务的人的工作

Create类商业方法更为明显。您当然不希望使用User实体作为参数,对于您的服务的消费者来说,知道实际需要的属性会非常复杂......

想象一下以下实体:

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

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

  • ID:dunno,也许它生成的可能不是
  • 名称/名字:那些应该设置
  • 密码:是一个纯文本密码,一个哈希版本?它是什么?
  • IsDeleted / IsActive:我应该自己激活用户吗?是通过业务方法完成的吗?
  • 个人资料:哼...如何影响用户的个人资料?
  • 事件:到底是那个??

它强迫您使用延迟加载

是的,我讨厌此功能有多种原因。其中一些是:

  • 非常难以有效使用。我看过太多次代码会产生数千个SQL请求,因为开发人员不知道如何正确使用延迟加载
  • 极难管理异常。通过允许随时执行SQL请求(即延迟加载),您将管理数据库异常的角色委派给上层,即业务层甚至应用程序。一个坏习惯。

使用POCO迫使您急切加载您的实体,更好的IMO。

关于AutoMapper

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