我最近听到人们说数据传输对象(DTO)是一种反模式.
为什么?有哪些替代方案?
传统上,当我试图从数据库中获取用户的数据时,我已经使用了以下方法(在某种程度上):
DbUsers curUser = context.DbUsers.FirstOrDefault(x => x.u_LoginName == id);
string name = curUser.u_Name;
string email = curUser.u_Email;
Run Code Online (Sandbox Code Playgroud)
您可以看到我想要做的就是获取名称和电子邮件,但在我看来,这个LINQ查询将所有内容存储在该用户的数据库中,将其恢复,然后允许我得到我想要的内容.
我一直在做一些研究,并找到了以下替代方案:
var current = from s in context.DbUsers
where s.u_LoginName == id
select new {
name = s.u_Name,
email = s.u_Email
};
foreach (var user in current)
{
//Stuff Here
}
Run Code Online (Sandbox Code Playgroud)
如果有的话哪个更好?当我只想检索一些结果/数据时,是否有更轻松的方法?
在具有域层(DL)/业务(服务)层(BL)/表示层(PL)的多层项目中,将实体传递到表示层的最佳方法是什么?
DO => Domain Object;
DTO = Domain Transfer Object;
VM => View Model;
V => View;
Run Code Online (Sandbox Code Playgroud)
选项1:
DL => DO => BL => DTO => PL => VM => V
Run Code Online (Sandbox Code Playgroud)
这个选项似乎是最佳实践,但似乎也很重要.
选项2:
DL => DO => BL => DTO => PL => V
Run Code Online (Sandbox Code Playgroud)
这个选项似乎不是很好的练习,但由于DTO与VM几乎完全相同,我们可以将它直接传递给View,实现和保护它不那么痛苦.
这个选项对于多个布局也是可靠的吗,例如,对于移动设备,我可能需要来自BL的较少信息,因此我需要为这个特定布局使用不同的VM?
我使用围绕DDD概念组织的域来处理标准Web应用程序.我想知道我的应用程序服务应该接受和返回什么样的对象.假设我有一个User聚合应用服务.
1)DTO /简单类型(字符串,整数等)
public interface UserApplicationService {
void registerUser(UserDTO userDTO);
List<UserDTO> getUsersForOrganization(String organizationId);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,应用程序服务负责调用汇编程序将DTO转换为域对象,反之亦然.
这种方法的优点是我的应用程序服务是我的域对象的明确边界.另一个是应用服务是一个明确的事务边界.由持久性上下文管理的域对象不会在事务之外的某处泄漏.
缺点是在表格的情况下,验证必须基于DTO.所以我的验证规则在域(对象负责其状态)和DTO验证规则之间重复.(与Spring MVC示例应用程序的情况一样).此外,如果视图的某些部分需要另一种形式的模型(假设UserDTO没有足够的信息来呈现视图),我将需要创建另一个DTO并基于从应用程序服务返回的几个DTO,构成另一个,由视图使用.
2)域类型
public interface UserApplicationService {
void registerUser(User user);
List<User> getUsersForOrganization(OrganizationId organizationId);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,控制器/演示者负责转换.
最大的缺点是我的域对象从应用程序服务泄漏 - 没有明确的分离.另外,我们的交易边界在哪里?可能附加到的域对象(例如Hibernate会话)在应用程序服务层之外泄漏.(但是,我注意到这是编写了多少个示例应用程序.)
优点可能是控制器/演示者负责准备视图模型,因此它可以根据视图要求构成DTO.例如,视图可能需要一些未在DTO中从#getUsersForOrganizationMethod返回的其他信息.此外,验证可能基于域对象,因此在DTO和域对象之间不会重复.
3)域对象+门面
这是DDDsample应用程序中使用的第三个选项.应用程序服务返回域类型,但有一些外观负责转换.所以在我的情况下,控制器/演示者使用DTO与外观进行对话,外观进行转换,并使用域对象与应用程序服务进行对话.然而,在我的拙见中,它看起来有点压倒性 - 层数太多,样板代码太多.对于一个应用程序服务,它可能听起来很棒,但如果我们有几十个,我们需要有相同数量的外观方法 - 纯复制.此外,交易边界在哪里?
在我的项目中,我正在使用EF Code First方法.我有一个存储库层,服务层和表示层(ASP.NET MVC).我正在为每个视图使用专用的视图模型.
我感到困惑的是,我的服务应该将实体返回到控制器以将它们映射到视图模型,还是应该实现DTO并从服务返回它们?
所以问题是当流程类似于"EF - >存储库 - >服务 - > UI"时,数据转换将是什么."实体 - > DTO - > Viewmodel"或"实体 - > Viewmodel"?
看起来如果我使用DTO,它们会有点重复实体.
我正在努力遵循最佳做法.
谢谢.
asp.net-mvc entity-framework dto repository-pattern viewmodel
我正在编写一个Spring(4.1.7)Web应用程序,该应用程序公开RESTful服务,并希望使用DTO"资源"对象在Controller和客户端浏览器之间进行通信,而不是公开我的持久性实体.
目前,该应用程序具有以下层:
@Service)@Repository)我的问题是,我应该将DAO实体映射到DTO资源?我看了一下用一些例子Spring HATEOAS,它们显示Resource延长对象ResourceSupport的映射Controller.这是最好的方法,还是我应该从DAO服务返回资源?
我想补充Link的元素返回的资源(为自己和相关的资源),但看不出Link是否在处理的元素将得到解决Service,而不必知识它Controller和它的@RequestMapping.另一方面,我不知道Controller将映射弄乱是否也是一种好的做法.
我正在使用Automapper将我的业务模型映射到ViewModel.
它有效,但速度很慢.
我有一个包含6893个对象的集合,有23个属性(测试环境,生产应该有更多).
使用循环00:02:32.8118534来映射所有内容.
var objects = // get all items (returns a collection of MyObj)
List<MyViewModel> collection = new List<MyViewModel>();
foreach (MyObj obj in objects)
{
MyViewModel vm = Mapper.Map<MyObj, MyViewModel>(obj);
collection.Add(vm);
}
Run Code Online (Sandbox Code Playgroud)
我试着像这样改进它:
var objects = // get all items (returns a collection of MyObj)
IEnumerable<MyViewModel> collection = mapper.Map<IEnumerable<MyObj>, IEnumerable<MyViewModel>>(objects);
Run Code Online (Sandbox Code Playgroud)
它00:02:25.4527961绘制了一切.
所以它没有那么多帮助.
我的对象的属性都不是null.
这是我配置映射器的方式:
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<MyObj, MyViewModel>();
cfg.CreateMap<MyObjOtherObj, MyViewModelOtherObj>();
});
mapper = config.CreateMapper();
Run Code Online (Sandbox Code Playgroud)
MyObj中:
public partial …Run Code Online (Sandbox Code Playgroud) 从我所阅读和实现的内容来看,DTO是从Data模型中保存值子集的对象,在大多数情况下,它们是不可变对象.
我需要传递新值还是更改回数据库的情况怎么样?
我应该直接使用我的表达层中的DAL中的数据模型/实际实体吗?
或者我应该创建一个可以从表示层传递到业务层的DTO,然后将其转换为实体,然后通过ORM调用在DB中进行更新.这写的代码太多了吗?我假设如果表示层没有数据模型的概念,则需要这样做.如果我们采用这种方法,我应该在提交更改之前在BLL层再次获取对象吗?
我在项目中使用服务层跟踪存储库模式.对于每个视图,我将创建一个viewmodel.
我感到困惑的是,服务层应该直接访问域对象并将它们返回给控制器,还是应该使用DTO.如果我应该使用DTO,将它们放在项目架构中的哪个位置?
谢谢.
dto ×5
asp.net-mvc ×3
automapper ×2
c# ×2
java ×2
viewmodel ×2
architecture ×1
ejb ×1
linq ×1
performance ×1
spring ×1
spring-mvc ×1