C# 实体框架类与POCO

C# 实体框架类与POCO,c#,entity-framework,architecture,poco,C#,Entity Framework,Architecture,Poco,我对建筑设计有着普遍的不同意见,尽管stackoverflow不应用于征求意见,但我想询问两种方法的优缺点,我将在下面描述: 详情: -C#应用 -SQL Server数据库 -使用实体框架 -我们需要决定使用什么对象来存储信息,并在整个应用程序中使用这些对象 情景1: 我们将使用实体框架实体通过我们的应用程序传递所有信息,例如,应该使用对象存储所有信息,我们将其传递给BL,最终我们的WepApi将获取该实体并返回值。没有DTO或POCO 如果数据库模式发生更改,我们将更新实体并在使用它的所有类

我对建筑设计有着普遍的不同意见,尽管stackoverflow不应用于征求意见,但我想询问两种方法的优缺点,我将在下面描述:

详情: -C#应用 -SQL Server数据库 -使用实体框架 -我们需要决定使用什么对象来存储信息,并在整个应用程序中使用这些对象

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

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

情景2: 我们创建一个中间类—称之为DTO或POCO—来保存应用程序所需的所有信息。有一个中间步骤,将存储在实体中的信息填入POCO,但我们将所有EF代码保留在数据访问中,而不是跨所有层


每种方法的优点和缺点是什么?

我有一个反问题:为什么不能两者兼而有之

考虑任意MVC应用程序。在模型和控制器层中,通常需要使用EF对象。如果您首先使用代码定义它们,那么实际上您已经首先定义了它们在应用程序中的使用方式,然后设计了持久化层,以便准确地保存应用程序中所需的更改

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


还请注意,当您使用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();
}
使用
void Create(用户实体)需要哪些属性方法

  • 不知道,可能是生成的,可能不是
  • Name/FirstName:应该设置这些
  • 密码:这是纯文本密码,是散列版本吗?这是什么
  • IsDeleted/IsActive:我应该自己激活用户吗?是通过商业方法完成的吗
  • 简介:哼。。。我如何影响用户的配置文件
  • 事件:这到底是什么
它强制您不要使用延迟加载 是的,我讨厌这个功能有多种原因。其中包括:

  • 极难有效地使用。我见过太多次生成数千个SQL请求的代码,因为开发人员不知道如何正确使用延迟加载
  • 非常难以管理异常。通过允许在任何时候执行SQL请求(即延迟加载),您可以将管理数据库异常的角色委托给上层,即业务层甚至应用程序。坏习惯
使用POCO迫使您急切地加载您的实体,这比IMO要好得多

关于汽车制造商
是一种工具,允许您自动将实体转换为POCO,反之亦然。我也不喜欢。请参见

stackoverflow不应用于征求意见您让我想到了这一点。我的观点是POCOs,我的朋友喜欢EF@ken2k的回答正是我想听到的,但现在我需要和我的朋友一起复习。谢谢你,理查德。
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; }
}