细节:
– C#应用程序
– sql Server数据库
– 使用实体框架
– 我们需要确定我们将使用哪些对象来存储我们的信息并在整个应用程序中使用所有对象
场景1:
我们将使用Entity Framework实体来遍历我们的应用程序,例如,该对象应该用于存储所有信息,我们将它传递给BL,最终我们的WepApi将获取此实体并返回值.没有DTO和POCO.
如果数据库模式发生更改,我们将更新实体并在使用它的所有类中进行修改.
场景2:
我们创建一个中间类 – 称之为DTO或称之为POCO – 以保存应用程序所需的所有信息.有一个中间步骤,即获取存储在实体中的信息并填充到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字段)……
它真正简化了消费您服务的人的工作
对于像商业方法这样的创造更为明显.您当然不希望使用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实体);方法?
> ID:不知道,也许它的产生可能不是
>名称/名字:那些应该设置
>密码:是一个纯文本密码,一个哈希版本?它是什么?
> IsDeleted / IsActive:我应该自己激活用户吗?是通过业务方法完成的吗?
>配置文件:哼…如何影响用户的个人资料?
>事件:到底是那个?
它迫使你不要使用延迟加载
是的,我讨厌这个功能有多种原因.他们之中有一些是:
>极难有效使用.我已经看到太多次代码产生了数千个sql请求,因为开发人员不知道如何正确使用延迟加载
>极难管理异常.通过允许随时执行sql请求(即延迟加载),您将管理数据库异常的角色委派给上层,即业务层甚至应用程序.一个坏习惯.
使用POCO迫使您急切加载您的实体,更好的IMO.
关于AutoMapper
AutoMapper是一个工具,允许您自动将实体转换为POCO,反之亦然.我也不喜欢它.见https://stackoverflow.com/a/32459232/870604