我正在构建我的第一个 SPA,并且我已经为我的每个实体构建了 DTO,但我刚刚发现轻而易举,它似乎负责将您的更改序列化为最小包以优化更新/添加/等等
我构建 DTO 的原因是为了“扁平化”我的数据并限制我将多少数据放在网络上,但我想知道如果 Breeze 处理它,我是否还需要这个开销。
我正在构建我的第一个 SPA,并且我已经为我的每个实体构建了 DTO,但我刚刚发现轻而易举,它似乎负责将您的更改序列化为最小包以优化更新/添加/等等
我构建 DTO 的原因是为了“扁平化”我的数据并限制我将多少数据放在网络上,但我想知道如果 Breeze 处理它,我是否还需要这个开销。
DTO 是有原因的。“扁平化数据”不是其中之一。“限制我在网络上传输的数据量”也不是。
Breeze 在对象图方面做得很好。想象一下为客户发送 100 个订单。您不想在每个订单 DTO 上重复客户名称。使用 Breeze,您可以查询客户订单(使用“扩展”),您会获得一份客户副本和与之配套的订单。
var 查询 = 新微风.EntityQuery.from('客户') .where('Id', 'eq', 42) .expand('订单');
另一方面,如果您只需要客户名称列表,请使用“投影”:
var query = new browse.EntityQuery.from('Customers') // 所有客户 .select('id, companyName'); // 投影到一个匿名的 2-property 对象中
偶尔使用服务器端 DTO 来构建您无法从客户端轻松创建的东西(例如,Customer-and-total-current-year-order-dollars)。
关键是您可以混合 DTO、投影和实体查询以满足您的需求。您不必一路走下去(在我看来)。
我们目前正在评估从 Knockout 到 Angular 和 Breeze 的更改,以摆脱我们编写的大部分 DTO 和 DTO 映射代码(服务器和客户端代码)。我们所做的不是公开 DAO,而是为所有实体创建 DTO。最后发生的事情是,在许多情况下(不是全部)我们有看起来 90% 与数据库对象相似的类。这使我们得出这样的结论:在我们的案例中,DTO 没有意义,我们所花费的开销是浪费精力,我们需要用更好的方法来摆脱这个问题。所以必须开始一轮重构:-)
由于这里我们有两位专家(@John 和@Ward)在一个地方,我也将借此机会回答这个问题,并进一步提出一个关于实施的问题,到目前为止我还没有完全回答我自己,也许是 John Ward 可以澄清这一点,因为我认为如果仍然需要 DTO,这是问题的重要方面。
看着微风,它似乎对避免大量 DTO 和 DTO 映射代码有很大帮助,我完全同意使用 DTO 来减少与微风一起通过电线的使用是没有意义的,因为这是完美处理的事情如上所述,通过微风在客户端进行查询。这是我可以完全确认并且有道理的事情。像我们一样创建许多不同的 DTO 类也不是最好的方法。Breeze 用更少的代码做得更好。
使用 DTO 和 DTO 映射代码来分离关注点我仍然认为是一个好主意和原则,但它也带来了很多开销,在许多情况下可能不需要。因此,要利用微风,您当然可以在客户端创建 DTO 并写入/生成元数据,但这不是微风的基本理念。你可以这样使用它,但是你在 DAO 上停留的时间越长,你需要编写的代码就越少,你的项目就越快。但是,breeze 允许您这样做,因此该框架也可以与 DTO 一起使用,但这并不是编写 BREW 的基本思想。两者的混合(DAO 和 DTO 的暴露)可能是最好的方法。
但是什么时候使用 DTO 呢?
在安全的情况下,我实际上不是 100% 确定,这就是我在这里写信并想问两位专家的原因。我们在服务器端使用 EF,最好的主意是在服务器端使用投影以确保安全。但是怎么做呢?
我提出这个问题是因为我认为如果仍然需要 DTO,能够回答这个问题是最重要的。
我们以 EF 的以下代码结束(在我们的评估演示中):
private IQueryable<News> RestrictFields(IQueryable<News> query)
{
return query
.ToList() // This seemd to be needed, otherwhise I cannot use new News()
.Select(t => new News()
{
Id = t.Id,
Text = t.Text,
Title = t.Title,
Date = t.Date
})
.AsQueryable();
}
正如您在上面看到的,我们有一个 EF 查询。所以我们尝试的第一个方法就是使用 new News() 进行投影。这不起作用,因为 EF 不允许您在投影中使用相同的 DAO 类,只能使用 DTO 对象或匿名对象。所以我们使用了 ToList() 和 AsQueryable() 的解决方法。但这似乎不正确,而且很可能来自客户端的查询参数不会发送到数据库,并且可能因此某些参数无法正常工作,例如“扩展”。
那么出于安全原因在服务器端进行投影的最佳方法是什么,以便最终真正摆脱对 DTO 的需求?@John:我看到了你的帖子,你说你在演示项目中为你的培训课程(Angular 和 Breeze)使用了扬声器上的投影,但我找不到它在哪里实现。
在这里我真的被困住了,这对我来说是了解是否仍然需要 DTO 以及它如何与 Breeze 完美配合的缺失环节。
我希望我的回答有助于回答您的一些问题,此外,我希望它还为您 Jake 提供了一些非常重要的有关使用微风以及是否仍然需要 DTO 的链接。
亲切的问候,
克里斯