Entity Framework 类 与 POCO
Entity Framework classes vs. POCO
我对架构设计有不同的看法,尽管不应使用 Whosebug 征求意见,但我想询问我将在下面描述的两种方法的优缺点:
详情:
- C# 应用程序
- SQL 服务器数据库
- 使用 Entity Framework
- 我们需要决定我们将使用哪些对象来存储我们的信息并在整个应用程序中使用所有对象
场景一:
我们将使用 Entity Framework 实体在我们的应用程序中四处传递,例如对象应该用于存储所有信息,我们将它传递给 BL,最终我们的 WepApi 将采用该实体和 return 价值。没有 DTO 和 POCO。
如果数据库架构发生变化,我们会更新实体并在所有 class 中使用它的地方进行修改。
场景二:
我们创建一个中间体 class - 称其为 DTO 或 POCO - 以保存应用程序所需的所有信息。有一个中间步骤是将存储在实体中的信息填充到 POCO 中,但我们将所有 EF 代码保留在数据访问中,而不是跨所有层。
各自的优缺点是什么?
我有一个反问:为什么不 两者都做?
考虑任意 MVC 应用程序。在模型和控制器层中,您通常希望使用 EF 对象。如果您使用 Code First 定义它们,那么您基本上已经定义了它们在您的应用程序中的使用方式 首先 然后设计您的持久层以准确地保存您在应用程序中需要的更改。
现在考虑将这些对象提供给视图层。这些视图可能反映也可能不反映您的对象,或者您的工作对象的集合。这通常会导致 POCOS/DTO 捕获视图中需要的任何内容。另一种情况是当您想要在 Web 服务中发布对象时。许多框架在 poco 类 上提供简单的序列化,在这种情况下,您通常需要 1) 注释您的 EF 类 或 2) 制作 DTO。
另请注意,当您使用 POCOS 或关闭上下文时,您可能在 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();
}
crystal弄清楚你的方法到底是什么returns。
现在想象一下,它返回了一个完整的 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: 不知道,也许是生成的也许不是
- Name/FirstName:那些应该被设置
- 密码:这是一个纯文本密码,一个散列版本?这是什么?
- IsDeleted/IsActive: 我应该自己激活用户吗?是通过业务方法完成的吗?
- 个人资料:嗯...我如何影响用户的个人资料?
- 事件:这是什么鬼??
它迫使你不使用延迟加载
是的,出于多种原因,我讨厌此功能。其中一些是:
- 极难有效使用。我见过太多次产生数千个 SQL 请求的代码,因为开发人员不知道如何正确使用延迟加载
- 极难管理异常。通过允许 SQL 请求在任何时候执行(即当您延迟加载时),您将管理数据库异常的角色委托给上层,即业务层甚至应用程序。一个坏习惯。
使用 POCO 会迫使您急切加载您的实体,IMO 更好。
关于 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
我对架构设计有不同的看法,尽管不应使用 Whosebug 征求意见,但我想询问我将在下面描述的两种方法的优缺点:
详情: - C# 应用程序 - SQL 服务器数据库 - 使用 Entity Framework - 我们需要决定我们将使用哪些对象来存储我们的信息并在整个应用程序中使用所有对象
场景一: 我们将使用 Entity Framework 实体在我们的应用程序中四处传递,例如对象应该用于存储所有信息,我们将它传递给 BL,最终我们的 WepApi 将采用该实体和 return 价值。没有 DTO 和 POCO。
如果数据库架构发生变化,我们会更新实体并在所有 class 中使用它的地方进行修改。
场景二: 我们创建一个中间体 class - 称其为 DTO 或 POCO - 以保存应用程序所需的所有信息。有一个中间步骤是将存储在实体中的信息填充到 POCO 中,但我们将所有 EF 代码保留在数据访问中,而不是跨所有层。
各自的优缺点是什么?
我有一个反问:为什么不 两者都做?
考虑任意 MVC 应用程序。在模型和控制器层中,您通常希望使用 EF 对象。如果您使用 Code First 定义它们,那么您基本上已经定义了它们在您的应用程序中的使用方式 首先 然后设计您的持久层以准确地保存您在应用程序中需要的更改。
现在考虑将这些对象提供给视图层。这些视图可能反映也可能不反映您的对象,或者您的工作对象的集合。这通常会导致 POCOS/DTO 捕获视图中需要的任何内容。另一种情况是当您想要在 Web 服务中发布对象时。许多框架在 poco 类 上提供简单的序列化,在这种情况下,您通常需要 1) 注释您的 EF 类 或 2) 制作 DTO。
另请注意,当您使用 POCOS 或关闭上下文时,您可能在 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();
}
crystal弄清楚你的方法到底是什么returns。
现在想象一下,它返回了一个完整的 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: 不知道,也许是生成的也许不是
- Name/FirstName:那些应该被设置
- 密码:这是一个纯文本密码,一个散列版本?这是什么?
- IsDeleted/IsActive: 我应该自己激活用户吗?是通过业务方法完成的吗?
- 个人资料:嗯...我如何影响用户的个人资料?
- 事件:这是什么鬼??
它迫使你不使用延迟加载
是的,出于多种原因,我讨厌此功能。其中一些是:
- 极难有效使用。我见过太多次产生数千个 SQL 请求的代码,因为开发人员不知道如何正确使用延迟加载
- 极难管理异常。通过允许 SQL 请求在任何时候执行(即当您延迟加载时),您将管理数据库异常的角色委托给上层,即业务层甚至应用程序。一个坏习惯。
使用 POCO 会迫使您急切加载您的实体,IMO 更好。
关于 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