我目前正在开发一个n层Web项目.在研究了数据传输对象及其优势后,我们决定采用这种模式.我们的ASP.NET MVC网站无法直接访问EF DbContext,而是使用DTO发送和接收实体数据.将有一个服务/映射层将在DTO和实体模型之间进行转换.
我的问题是,将实体模型导航属性转换为DTO的最佳方法是什么?
以下是项目中实体模型及其DTO的示例:
实体模型:
public class Payment
{
public int ID { get; set; }
public DateTime? PaidOn { get; set; }
public decimal Amount { get; set; }
public string Reference { get; set; }
//Navigation Properties
public virtual PaymentMechanism PaymentMechanism { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
DTO:
public class PaymentDto
{
public int ID { get; set; }
public DateTime? PaidOn { get; set; }
public decimal Amount { …Run Code Online (Sandbox Code Playgroud) 我正在开发一个Spring Boot项目.我只有注释配置.我想包括推土机将实体转换为DTO,将DTO转换为实体.我在dozer网站上看到,他们解释说我必须在spring xml配置文件中添加以下配置.由于我没有xml文件而是注释配置Java类,我不知道如何将其转换为Java Configuration类.
<bean id="org.dozer.Mapper" class="org.dozer.DozerBeanMapper">
<property name="mappingFiles">
<list>
<value>dozer-global-configuration.xml</value>
<value>dozer-bean-mappings.xml</value>
<value>more-dozer-bean-mappings.xml</value>
</list>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
如果有人能给我一个例子,它会非常有用.谢谢
我有一个项目,我们使用屏幕DTO来封装服务层和表示层之间的数据.在我们的例子中,表示层是ASP.Net.
唯一知道DTO的类是服务层类和调用这些服务并显示DTO的Pages/Controls.
DTO几乎总是特定于页面/控件,因此我觉得它们属于表示层,但这意味着服务层必须引用表示层才能使用DTO.
我几乎认为服务层应该返回更丰富的对象(但不是域实体?)然后表示层可以获取这些对象并将它们映射到每个页面/控件关注点的非常特定的DTO.
这是一个界面声明和一个DTO,所以你可以看到我在说什么:
public interface IBlogTasks
{
BlogPostDisplayDTO GetBlogEntryByTitleAndDate(int year, int month, string urlFriendlyTitle);
}
public class BlogPostDisplayDTO
{
public string Title { get; set; }
public DateTime PostDate { get; set; }
public string HtmlContent { get; set; }
public string ImageUrl { get; set; }
public string Author { get; set; }
public int CommentCount { get; set; }
public string Permalink { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
编辑
这是另一个代码示例,用于描述不涉及Domain模型的用例.也许这会澄清一些事情.我相信我已经超载了DTO的含义.我不是在谈论DTO在线上传输物体的功能.我正在创建DTO以正式化与我的服务层之间的通信合同.
public interface IAuthenticationTasks …Run Code Online (Sandbox Code Playgroud) 我开始考虑跟踪断开连接的应用程序中复杂对象图的变化.我已经找到了几个解决方案,但我想知道您是否有最佳实践或使用什么解决方案,为什么?我把同样的问题传递给了MSDN论坛,但我只收到了一个答案.我想从其他开发人员的经验中学到更多答案.
这个问题与.NET有关,所以对于实现细节的答案,我更喜欢与.NET世界相关的答案,但我认为在其他平台上也是如此.
我的案例中的理论问题是在多层架构中定义的(目前不一定是n层),如下所示:
现在假设其中一个域对象是具有订单详细信息(行)和相关订单的订单.当客户请求订购时,它可以修改订单,添加,删除或修改任何订单明细,以及添加或删除相关订单.所有这些修改都是在Web浏览器中的数据上完成的 - javascript和AJAX.因此,当客户端按下保存按钮时,所有更改都会在单个镜头中提交.问题是如何处理这些变化?存储库和ORM工具需要知道修改,插入或删除了哪些实体和关系.我以两个"最佳"解决方案结束:
将DTO的初始状态存储在隐藏字段中(更糟糕的是会话).当接收保存更改的请求时,基于接收的数据创建新的DTO,并基于持久的数据创建第二个DTO.合并这两个并跟踪更改.将合并的DTO发送到外观层,并使用收到的有关更改的信息来正确设置实体图.这需要在域对象中进行一些手动更改跟踪,以便可以从头开始设置更改信息,然后将其传递到存储库 - 这是我不太满意的一点.
根本不跟踪DTO中的更改.当在Facade层中接收修改后的数据时,创建修改后的实体并从存储库加载实际状态(通常是对数据库的附加查询 - 这是我不太满意的一点) - 合并这两个实体并自动跟踪ORM工具提供的实体代理的更改(实体框架4.0和NHibernate允许这样).并发处理需要特别小心,因为实际状态不必是初始状态.
你觉得怎么样?您有什么推荐的吗?
我知道通过在某些应用程序层上使用缓存可以避免一些这些挑战,但这是我目前不想使用的.
我对这个话题的兴趣甚至更进一步.例如,假设应用程序进入3层体系结构,而客户端(Web应用程序)将不会用.NET编写= DTO类无法重用.跟踪DTO的变化将要困难得多,因为它需要其他开发团队在其开发工具中正确实现跟踪机制.
我相信这些问题必须在很多应用中解决,请分享你的经验.
我正试图围绕领域驱动开发.我想确保我有一个良好的基础和理解它,所以如果在这里避免使用AutoMapper或类似的建议会很好.我的架构目前涉及以下内容:

WCF服务负责持久性(使用实体框架)和服务器端验证.它将POCO转换为DTO,并将DTO转移到客户端.
客户接收DTO并将其转换为POCO.转换POCO和DTO的类在服务和客户端之间共享.
POCO的实现IValidatableObject和INotifyPropertyChanged服务器和客户端都使用它们,但它们不用于数据传输.DTO是,只是不包含任何行为的财产袋.
(1)问题#1.此架构是否适用于域驱动设计.
(2)问题#2.POCO是否适合包含导航属性?对于POCO来说,在DDD架构中包含导航属性对我来说真的是错误的,因为对我来说,拥有可能序列化或不序列化的导航属性是没有意义的.拥有专门的DTO对我来说更有意义.
例如,这是POCO/DTO在我的架构中的样子.
// Enforces consistency between a POCO and DTO
public interface IExample
{
Int32 Id { get; set; }
String Name { get; set; }
}
// POCO
public class Example : IExample, INotifyPropertyChanged, IValidatableObject
{
private int id;
private string name;
public Int32 Id {
get { return this.id; }
set {
this.id = value;
OnPropertyChanged("Id");
}
}
public String Name {
get { return …Run Code Online (Sandbox Code Playgroud) 我有一个使用Web Api构建的聊天应用程序后端,我将几个数据库实体直接暴露给客户端.我想知道是否有任何积极的观点将实体映射到DTO,或者我是否应该像我目前一样继续暴露实体.只是为了澄清我不是要求DTO与非DTO一般性问题,而只是在这种情况下使用它的优点,因为实体中的大多数字段可能会被客户端使用.
我已经阅读了很多关于这些内容的内容,而且我目前正在开发一个更大的Web应用程序及其相应的后端.
但是,我开始使用一种设计,我要求Repository从数据库中获取数据并将其映射到DTO.为何选择DTO?仅仅因为到目前为止基本上一切都是简单的东西,不再需要复杂性.如果它有点复杂,那么我开始直接在服务层中映射例如1到n的关系.就像是:
// This is Service-Layer
public List<CarDTO> getCarsFromOwner(Long carOwnerId) {
// Entering Repository-Layer
List<CarDTO> cars = this.carRepository = this.carRepository.getCars(carOwnerId);
Map<Long, List<WheelDTO>> wheelMap = this.wheelRepository.getWheels(carId);
for(CarDTO car : cars) {
List<WheelDTO> wheels = wheelMap.get(car.getId());
car.setWheels(wheels);
}
return cars;
}
Run Code Online (Sandbox Code Playgroud)
这当然是有效的,但事实证明,有时事情变得比这更复杂,我开始意识到,如果我不对此做任何事情,代码可能看起来很丑陋.
当然,我可以加载wheelMap,在CarRepository那里进行轮映射,只返回完整的对象,但由于SQL查询有时看起来很复杂,我不想获取所有cars 和他们的wheels加号处理映射getCars(Long ownerId).
我显然错过了商业层,对吗?但我根本无法理解其最佳实践.
我们假设我有Car一个Owner业务对象.我的代码看起来像这样:
// This is Service-Layer
public List<CarDTO> getCarsFromOwner(Long carOwnerId) {
// The new Business-Layer
CarOwner carOwner = new CarOwner(carOwnerId);
List<Car> …Run Code Online (Sandbox Code Playgroud) 我们正在使用Spring Boot创建rest api。我们的项目分为三层(存储库,服务和控制器)。
可以说我的控制器中有GetUser api,它返回UserDTO对象。
@GetMapping
public UserDTO getUser() {
return userService.getUser();
}
Run Code Online (Sandbox Code Playgroud)
是userService.getUser()返回UserDTO对象还是返回User对象并将其转换为UserDTO控制器中的对象?哪个更好的方法?
不久,域对象到DTO对象的转换应该在服务层还是控制器层进行?
我正在使用 OpenAPI 3.0 设计和实现一个简单的 API,以允许对数据库实体进行基本的 CRUD 操作。
让我们假设一个实体Pet具有一些客户端给定的属性 ( name& age) 和一些生成的属性 ( id& created):
components:
schemas:
Pet:
type: object
properties:
id:
type: string
created:
type: string
format: date-time
name:
type: string
age:
type: integer
Run Code Online (Sandbox Code Playgroud)
我想指定 REST 端点来 POST、GET、PUT(如果可能的话 PATCH)宠物:
paths:
/pets:
post:
operationId: createPet
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
responses:
"200":
content:
application/json:
schema:
type: boolean
/pets/{id}:
parameters:
- name: id
schema:
type: string
in: path
required: true
get:
operationId: getPet
responses: …Run Code Online (Sandbox Code Playgroud) dto ×10
asp.net ×2
c# ×2
java ×2
.net ×1
annotations ×1
architecture ×1
asp.net-mvc ×1
chat ×1
dozer ×1
layer ×1
nullable ×1
openapi ×1
orm ×1
poco ×1
rest ×1
spring ×1
swagger ×1
unit-testing ×1