如何在初始化子项时引用聚合根的属性/字段

本文关键字:属性 字段 引用 初始化 | 更新日期: 2023-09-27 18:36:40

假设我有两个域类 Order 和 OrderItem 其中 Order 充当包含一个或多个订单项的聚合根。如下:

    class OrderItem
    {
        public long LineItemId { get; set; }
        public String ProductId { get; set; }
        public DateTime CreatedDate { get; set; }
    }
    class Order
    {
        public long OrderId { get; set; }
        public DateTime OrderDate { get; set; }
        public String OrderStatus { get; set; }
        public OrderItem[] OrderItems { get; set; }
        public DateTime CreatedDate { get; set; }
    }

现在,在初始化 Order 对象及其行项时,是否可以在子项初始值设定项中引用或访问聚合的根属性/字段,如下所示:

        var order = new Order
        {
            OrderId = 1,
            OrderDate = new DateTime(2012, 6, 1),
            OrderStatus = "OPEN",
            CreatedDate = DateTime.Now,
            OrderItems = new[]
                                {
                                    new OrderItem {
                                        LineItemId = 1,
                                        ProductId = "Orange",
                                        CreatedDate = ??? // Initialize this to order's CreatedDate
                                    },
                                    new OrderItem {
                                        LineItemId = 2,
                                        ProductId = "Pear",
                                        CreatedDate = ??? // Initialize this to order's CreatedDate
                                    }
                                }
        };

这里的目标是确保订单项与订单具有相同的时间戳(创建日期) - 到 T。这是否可以轻松实现 - 无需(当然)引入额外的变量来保存 CreatedDate?

如何在初始化子项时引用聚合根的属性/字段

您不能在初始值设定项中引用父级的变量,但我认为以下内容以类似的方式完成了您尝试执行的操作:

var order = new Order
{
    OrderId = 1,
    OrderDate = new DateTime(2012, 6, 1),
    OrderStatus = "OPEN",
    CreatedDate = DateTime.Now
};
order.OrderItems = new[]{
    new OrderItem {
        LineItemId = 1,
        ProductId = "Orange",
        CreatedDate = order.CreatedDate
    },
    new OrderItem {
        LineItemId = 2,
        ProductId = "Pear",
        CreatedDate = order.CreatedDate
    }};

不能引用正在初始化的对象。出于一个简单的原因,它将允许您轻松创建一个循环。

在您的情况下,可以通过将订单的创建时间戳移动到构造函数中并将 OrderItems 属性更改为

public OrderItem[] OrderItems
{
    get
    {
        return this.orderItems;
    }
    set
    {
        this.orderItems = value;
        foreach (var item in this.orderItems)
        {
            item.CreatedDate = this.OrderDate;
        }
    }           
}

并可能使订单日期成为只读。如果你必须有一个无参数的构造函数,你也可以在 OrderDate 中实现 foreach-loop 并使用私有字段支持它 - 这样一切都会同步。

为了完整起见,不使用构造函数时的 OrderDate:

public DateTime OrderDate
{
    get
    {
        return this.orderDate;
    }
    set
    {
        this.orderDate = value;
        foreach (var item in this.orderItems)
        {
            item.CreatedDate = this.OrderDate;
        }
    }
}

补充一点,我很确定我会将部分/大部分内容移动到构造函数中 - 尤其是时间戳是它的主要候选者,与 Id 相同,因为这样您就可以使它们对公共public OrderId [ get; private set; }只读。另外,我建议使用OrderStatus的枚举。