在本系列前面的文章中, 我们主要讨论了产品上下文与经销商上下文相关的实现, 大家对 DDD 的方法与架构已经有了初步的了解.
但是在这两个界限上下文中, 业务逻辑很简单, 也没有用到更多的值对象的内容. 从这篇文章开始, 我们来讲讲订单界限上下文实现的内容,
里面的业务逻辑相对复杂一些, 而且有大量值对象的引入来进行逻辑的处理.
订单上下文的需求主要是生成相应的订单项, 每个订单项中有相关的订单产品和购买数量并生成订单项总额, 订单项总 PV, 同时订单项总额
和订单项总 PV 会累加到订单总额和订单总 PV 中, 同时会根据订单总额扣减当前经销商的电子币, 也会根据购买产品的 PV, 累加当前经销商的 PV 值.
1. 订单界限上下文的领域模型:
从上图的领域模型中, 大家可以看出订单是聚合根, 订单明细是聚合的实体; 订单聚合根总有总价, 总 PV, 收获地址三个值对象, 订单明细实体有
明细总价, 明细总 PV, 产品信息三个值对象.
2. 明细总价值对象:
- public partial class OrderItemTotalPrice
- {
- public decimal SubTotalPrice { get; set; }
- }
3. 明细总 PV 值对象:
- public partial class OrderItemTotalPV
- {
- public decimal SubTotalPV { get; set; }
- }
4. 产品信息值对象:
- public partial class ProductSKUs
- {
- public string ProductSPUName { get; set; }
- public decimal ProductPrice { get; set; }
- public decimal ProductPV { get; set; }
- public Guid ProductSKUId { get; set; }
- }
5. 订单明细实体:
- public partial class OrderItem : IEntity
- {
- public string Code { get; set; }
- [Key]
- public Guid Id { get ; set ; }
- public OrderItemTotalPrice OrderItemTotalPrice { get; set; }
- public OrderItemTotalPV OrderItemTotalPV { get; set; }
- public ProductSKUs ProductSKUs { get; set; }
- public int Count { get; set; }
- }
订单明细实体引入了 OrderItemTotalPrice,OrderItemTotalPV,ProductSKUs 三个值对象, 同时具有自己的 Code 与 Count 两个属性.
6. 订单总价对象:
- public partial class OrderTotalPrice
- {
- public decimal TotalPrice { get; set; }
- }
7. 订单总 PV 值对象:
- public partial class OrderTotalPV
- {
- public decimal TotalPV { get; set; }
- }
8. 订单收货地址值对象:
- public partial class OrderStreet
- {
- // 省
- public string Privince { get; set; }
- // 市
- public string City { get; set; }
- // 区 (县)
- public string Zero { get; set; }
- // 街道地址
- public string Street { get; set; }
- }
9. 订单聚合根:
- public partial class Orders : IAggregationRoot
- {
- public string Code { get; set ; }
- [Key]
- public Guid Id { get ; set; }
- public OrderStreet OrderStreet { get; set; }
- public OrderTotalPV OrderTotalPV { get; set; }
- public OrderTotalPrice OrderTotalPrice { get; set; }
- public DateTime OrderDateTime { get; set; }
- public Guid OrderDealerId { get; set; }
- public List<OrderItem> OrderItems { get; set; }
- public string Telephone { get; set; }
- }
订单聚合根引入了 OrderStreet,OrderTotalPV,OrderTotalPrice 三个值对象; Code,DateTime(下单时间),Telephone(联系电话),OrderItems(订单项实体集) 等几个属性.
10. 生成数据库表:
根据前面文章的说明, 我们可以依据上述 POCO 模型生成对应的数据库表, 要注意的是, OrderItems 可以自动识别为 Orders 的关联表, 其他几个值对象我们要考虑是否是生成
单独的表还是作为相关实体或聚合根的表的列存在, 一般情况下, 我们是将这些值对象作为相关聚合根或实体表的列存在的. EF Core 无法自动处理这些值对象如何存储到数据库中,
我们需要手工指定:
- public class OrderEFCoreContext:DbContext,IOrderContext
- {
- public DbSet<Orders> Order { get; set; }
- public DbSet<OrderItem> OrderItem { get; set; }
- protected override void OnConfiguring(DbContextOptionsBuilder optionBuilder)
- {
- optionBuilder.UseSqlServer("数据库连接字符串");
- }
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- modelBuilder.Entity<Orders>().OwnsOne(p => p.OrderStreet);
- modelBuilder.Entity<Orders>().OwnsOne(p => p.OrderTotalPrice);
- modelBuilder.Entity<Orders>().OwnsOne(p => p.OrderTotalPV);
- modelBuilder.Entity<OrderItem>().OwnsOne(p => p.OrderItemTotalPrice);
- modelBuilder.Entity<OrderItem>().OwnsOne(p => p.OrderItemTotalPV);
- modelBuilder.Entity<OrderItem>().OwnsOne(p => p.ProductSKUs);
- }
从上面代码可以看出, 在 OnModelCreating 时, 可以指定 6 个值对象包含在对应的聚合根和实体相关的表中.
来源: https://www.cnblogs.com/malaoko/p/9092967.html