Javascript Breeze是否消除了单页应用程序中对DTO的需求?
我正在构建我的第一个SPA,我已经为我的每个实体构建了DTO,但我刚刚发现breeze,它似乎负责将您的更改序列化为最简单的包,以优化更新/添加/等等Javascript Breeze是否消除了单页应用程序中对DTO的需求?,javascript,design-patterns,dto,breeze,single-page-application,Javascript,Design Patterns,Dto,Breeze,Single Page Application,我正在构建我的第一个SPA,我已经为我的每个实体构建了DTO,但我刚刚发现breeze,它似乎负责将您的更改序列化为最简单的包,以优化更新/添加/等等 我构建DTO的原因是为了“展平”我的数据并限制我在线路上放置的数据量,但我想知道如果Breeze处理好它,我是否需要这种开销 DTO的存在是有原因的。“数据扁平化”不是其中之一。也不是“限制我在网络上输入的数据量” Breeze在对象图方面做得很好。想象一下为一位客户发送100份订单。您不希望在每个订单DTO上重复客户名称。使用Breeze,您可
我构建DTO的原因是为了“展平”我的数据并限制我在线路上放置的数据量,但我想知道如果Breeze处理好它,我是否需要这种开销 DTO的存在是有原因的。“数据扁平化”不是其中之一。也不是“限制我在网络上输入的数据量” Breeze在对象图方面做得很好。想象一下为一位客户发送100份订单。您不希望在每个订单DTO上重复客户名称。使用Breeze,您可以查询客户订单(使用“展开”)并获得一份客户和订单的副本 var query = new breeze.EntityQuery.from('Customers') .where('Id', 'eq', 42) .expand('orders'); var query=new breeze.EntityQuery.from('客户') 其中('Id','eq',42) .扩展(“订单”); 另一方面,如果您只需要客户姓名列表,请使用“投影”: var query=new breeze.EntityQuery.from('Customers')//所有客户 .选择('id,companyName');//投影到匿名2属性对象中 偶尔使用服务器端DTO构建一些您无法从客户端轻松创建的东西(例如,客户和当前年度订单总额)
关键是,您可以混合使用DTO、投影和实体查询来满足您的需要。在我看来,您不必走这条路或那条路。我们目前正在评估从Knockout到Angular和Breeze的变化,以摆脱我们编写的大部分DTO和DTO映射代码(服务器端和客户端代码)。我们所做的不是公开DAO,而是为所有实体创建DTO。最后发生的事情是,我们在很多情况下(不是所有情况下)类看起来90%类似于数据库对象。这让我们得出结论,在我们的案例中,DTO没有意义,我们所花费的开销是徒劳的,我们需要用更好的方法来解决这个问题。因此,必须开始一轮重构:-) 既然这里有两位专家(@John和@Ward),我也会借此机会回答这个问题,并进一步提出一个关于实施的问题,到目前为止我还没有完全回答过,也许John和Ward可以澄清这一点,因为我认为这是问题的一个重要方面,如果DTO仍然需要的话 看看breeze,它似乎对避免大量DTO和DTO映射代码非常有帮助,我完全同意使用DTO与breeze一起减少传输量是没有意义的,因为正如上面在客户端的查询中所解释的那样,breeze可以完美地处理这一点。这是我完全可以证实的,也是有道理的。像我们这样创建许多不同的DTO类并不是最好的方法。Breeze用更少的代码做得更好 我仍然认为使用DTO和DTO映射代码来分离关注点是一个好主意和原则,但它也带来了很多开销,在许多情况下可能不需要这些开销。所以,为了利用breeze,您当然可以在客户端创建DTO和编写/生成元数据,但这不是breeze的基本思想。您可以这样使用它,但是您在DAOs上停留的时间越长,您需要编写的代码就越少,项目也就越快。但无论如何,breeze允许您这样做,因此框架也将与DTO一起工作,这并不是编写breeze的基本理念。两者的混合(DAO和DTO的曝光)可能是最好的方法 但是什么时候使用DTO呢
- 保安
- 复杂的逻辑(计算)或无法使用简单的CRUD方法时,因为 太多的复杂性,您不会或不能(安全性)在客户端公开
专用IQueryable限制字段(IQueryable查询)
{
返回查询
.ToList()//这似乎是必需的,否则我不能使用new News()
.Select(t=>newnews()
{
Id=t.Id,
Text=t.Text,
Title=t.Title,
日期=t.日期
})
.AsQueryable();
}
正如您在上面看到的,我们有一个EF查询。因此,我们首先尝试的是使用新新闻()进行投影。这不起作用,因为EF不允许在投影中使用相同的DAO类,只允许对对象或匿名对象使用DTO。因此,我们使用了ToList()和AsQueryable()的变通方法。但是这似乎不正确,而且可能来自客户端的查询参数没有被发送到数据库,并且可能因为这个原因一些查询参数无法工作,比如“expand”
那么,出于安全考虑,在服务器端进行投影的最佳方法是什么,以便最终真正摆脱对DTO的需求@约翰:我看到你的一篇帖子,你说,你在培训班的演示项目(Angular and Breeze)中使用了扬声器的投影,但我找不到这是在哪里实现的
在这里,我真的被卡住了,这是我缺少的一个环节,我想知道是否仍然需要DTO,以及它如何与Breeze完美地协同工作
我希望我的回答能帮助你回答一些问题,而且我也希望它能为你杰克提供一些非常重要的信息
var query = new breeze.EntityQuery.from('Customers') // all customers
.select('id, companyName'); // project into an anonymous 2-property object
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();
}