.NET Core 2.2中的DDD实体,从属性获取

时间:2019-05-04 18:50:57

标签: c# entity-framework-core domain-driven-design

在此问题中,如果我使用 Entity 一词,则是指DDD实体,除非我明确声明我在谈论EF核心实体< / em>

我一直在阅读Microsoft's documentation关于.NET Core的DDD模式。

我还一直在研究他们创建的GitHub repo,其中包含上述文档中描述的实现。具体来说,我正在查看in.next()聚合(链接指向的位置)。

问题的背景

我试图了解它们如何实现Order.cs属性。

如您所见,Enumeration类型类似于值对象,但是是建模行为类似于枚举的更方便的方法(imho)。

使用Enumeration类型的DDD实体的摘录(完整的实体在上面的repo链接中):

Enumeration

问题

以这种方式实现属性意味着,每当您public class Order : Entity, IAggregateRoot { public OrderStatus OrderStatus { get; private set; } private int _orderStatusId; public Order() { _orderStatusId = OrderStatus.Submitted.Id; } } get属性时,它就是OrderStatus

我知道将实体封装在DDD中是头等大事,但是可以肯定的是,只有在修改状态时才需要担心。实施null方法似乎只是读取属性值的一种很简单的方法:

GetOrderStatus

我想到的唯一一件事就是实现如下所示的属性,但这破坏了EF Core:

public class Order
    : Entity, IAggregateRoot
{
    public OrderStatus OrderStatus { get; private set; }
    private int _orderStatusId;

    public Order()
    {
        _orderStatusId = OrderStatus.Submitted.Id;
    }

    public OrderStatus GetOrderStatus()
    {
        return Enumeration.FromValue<OrderStatus>(_orderStatusId);
    }
}

有没有更清洁的方法来实现这一目标?

1 个答案:

答案 0 :(得分:0)

如果它是值类型,为什么不将其视为值类型(在EF核心术语Owned Entity中)?

拥有的类型基本上是没有身份的类型(它们不是由ID标识,而是由其整个值标识)。在幕后,所有拥有类型的属性都将转换为拥有实体的列名。

这是将值类型映射到关系数据库的绝佳方法,您不必在模型中添加标识(id)列。常见的示例是订单上的Address

如果这不能满足您的需求,则可以使用Value Converter将类型转换为数据库可以理解的类型(即enum->字符串而不是enum id)。这可用于将id(或字符串)转换为适当的值类型并进行分配。

通常,您的问题来自于将持久性知识泄漏到您的域中,__orderStatusId与关系存储相关,在您的域中绝对没有意义。在设计DDD模型时,您绝对必须避免这种情况。

DDD模型永远不会受到持久性技术的影响(例如,具有数据库或ORM映射器所需的构造函数,具有值类型的ID,因为它们“映射”到数据库表等)。

使用转换器,您可以将值类型转换为id并将id转换为值类型,并使用

var converter = new ValueConverter<OrderStatus, int>(
    v => v.Id,
    v => Enumeration.FromValue<OrderStatus>(v));

modelBuilder
    .Entity<Order>()
    .Property(e => e.OrderStatus)
    .HasConversion(converter);