entity framework类与POCO

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

详细信息: – C#应用程序 – SQL Server数据库 – 使用entity framework – 我们需要确定我们将使用哪些对象来存储我们的信息并在整个应用程序中使用所有对象

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

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

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

每个人的利弊是什么?

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

我看到直接使用EF实体的唯一优势是它编写的代码更少……

改为使用POCO的优点:

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

基本上,假设您有一些GetUsers业务方法。 如果你只是想让用户列表填充一个网格(例如你需要他们的ID,名字,名字),你可以写下这样的东西:

 public IEnumerable 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 Profiles { get; set; } public virtual ICollection Events { get; set; } } 

使用void Create(User entity);所需的属性void Create(User entity); 方法?

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

它迫使你不要使用延迟加载

是的,我讨厌这个function有多种原因。 他们之中有一些是:

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

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

关于AutoMapper

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

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

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

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

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