使用EntityFramework持久化聚合
目录
背景返回目录
DDD中只有聚合根可以有仓储,仓储负责整个聚合持久化的相关生命周期,在不使用工作单元或POCO的情况下,我们可以让Order内部直接调用DAL操作OrderItem。我们也可以让Order跟踪所有OrderItem的状态,然后在OrderRepository内部操作OrderItem。如果我们采用了重量级的ORM工具,如:EntityFramework,事情会不会变得简单呢?
使用EntityFramework持久化聚合返回目录
关键思路:双主键。
示例聚合
这里以订单和订单项为例。
Order管理OrderItem

1 public void AddOrderItem(OrderItem item)
2 {
3 item.MustNotNull("item");
4
5 this.State.BeforeChangeOrder();
6
7 item.OrderId = this.Id;
8 this.OrderItemCollection.Add(item);
9 this.Total += item.Subtotal;
10 }
11
12 public void RemoveOrderItem(Guid productId)
13 {
14 this.State.BeforeChangeOrder();
15
16 var item = this.OrderItemCollection.First(x => x.ProductId == productId);
17 this.OrderItemCollection.Remove(item);
18 this.Total -= item.Subtotal;
19 }

映射配置

1 modelBuilder
2 .Entity<OrderItem>()
3 .HasKey(x => new { x.Id, x.OrderId });
4
5 modelBuilder
6 .Entity<Order>()
7 .HasKey(x => x.Id);
8 modelBuilder
9 .Entity<Order>()
10 .Property(x => x.OptimisticKey).IsRowVersion().IsConcurrencyToken();
11 modelBuilder
12 .Entity<Order>()
13 .HasMany(x => x.OrderItemCollection).WithRequired().HasForeignKey(x => x.OrderId).WillCascadeOnDelete();

注意:上面为OrderItem配置了双主键,如果不这么配置,删除逻辑会错误,要么删除后提交失败,要么OrderItem的数据库记录还在,只是OrderId变为NULL了。
备注返回目录
考虑到聚合内非聚合根的实体都具有“本地标识”,采用“双主键”就非常合理了,这个错误新手经常犯的。
再说一个题外话,聚合内的实体的标识能被其它聚合引用吗?我觉得应该是可以的,前提是必须同时引用其完整的标识,即:双主键。
使用EntityFramework持久化聚合的更多相关文章
- DDD:使用EntityFramework的话,如果只为聚合根设计仓储,其它实体如何处理?
背景 DDD中只有聚合根可以有仓储,仓储负责整个聚合持久化的相关生命周期,在不使用工作单元或POCO的情况下,我们可以让Order内部直接调用DAL操作OrderItem.我们也可以让Order跟踪所 ...
- 关于实现一个基于文件持久化的EventStore的核心构思
大家知道enode框架的架构是基于ddd+event sourcing的思想.我们持久化的不是聚合根的最新状态,而是聚合根产生的领域事件.最近我在思考如何实现一个基于文件的eventstore.目标有 ...
- EntityFramework 学习 一 Persistence in Entity Framework
实体框架的持久化 当用EntityFramework持久化一个对象时,有两种情形:连接的和断开的 1.连接场景:使用同一个context上下文从数据库中查询和持久化实体时,查询和持久化实体期间,con ...
- 认证授权:IdentityServer4 - 数据持久化
前言: 前面的文章中IdentityServer4 配置内容都存储到内存中,本篇文章开始把配置信息存储到数据库中:本篇文章继续基于github的代码来实现配置数据持久化到MySQL中 一.基于EFCo ...
- [.NET领域驱动设计实战系列]专题二:结合领域驱动设计的面向服务架构来搭建网上书店
一.前言 在前面专题一中,我已经介绍了我写这系列文章的初衷了.由于dax.net中的DDD框架和Byteart Retail案例并没有对其形成过程做一步步分析,而是把整个DDD的实现案例展现给我们,这 ...
- ENode 2.6 架构与设计简介以及全新案例分享
前言 ENode是一个应用开发框架,为开发人员提供了一整套基于DDD+CQRS+ES+EDA架构风格的解决方案.ENode从发布1.0开始到现在的差不多两年时间,我几乎每周都在更新设计或实现代码.以至 ...
- ENode 1.0 - 整体架构介绍
前言 今天是个开心的日子,又是周末,可以安心轻松的写写文章了.经过了大概3年的DDD理论积累,以及去年年初的第一个版本的event sourcing框架的开发以及项目实践经验,再通过今年上半年利用业余 ...
- Storm入门(十三)Storm Trident 教程
转自:http://blog.csdn.net/derekjiang/article/details/9126185 英文原址:https://github.com/nathanmarz/storm/ ...
- .net core 2.x - ids4 - identity - two factory 登录认证
本片内容使用到ids4+ids4.Entityframework持久化表单,以及core的identity相关表的一并持久化,然后就是登录认证,认证使用email发送邮件的方式.所以这里涉及到四块内容 ...
随机推荐
- Oracle 指数 一个简短的引论
1 索引创建语法: CREATE UNIUQE | BITMAP INDEX <schema>.<index_name> ON <schema>.< ...
- Swift的笔记和参考
原文:Swift的笔记和参考 好久没来了,趁着新语言Swift发布,继续钻研中! Create Class 创建类 (多态效果) // Create Class 创建类 class MyClass { ...
- jsp的<%%>
于jsp于 可以使用<% %> 嵌入java代码,简称jsp文字. 可以使用<% -- -- %> 凝视,这是jsp注视 可以使用<%! %> 声明全局变量 版权声 ...
- veridata实验举例(2)验证表BONUS与表SALGRADE两节点同步情况
veridata实验举例(2)验证表BONUS与表SALGRADE两节点同步情况 续接前几篇文章: 1.GoldenGate配置(一)之单向复制配置 地址:点击打开链接 2.GoldenGate配置( ...
- ajax form表单提交 input file中的文件
ajax form表单提交 input file中的文件 现今的主流浏览器由于ajax提交form表单无法把文件类型数据提交到后台,供后台处理,可是开发中由于某些原因又不得不用ajax提交文件, 为了 ...
- SQL Server中存储过程比直接运行SQL语句慢的原因
原文:SQL Server中存储过程比直接运行SQL语句慢的原因 在很多的资料中都描述说SQLSERVER的存储过程较普通的SQL语句有以下优点: 1. 存储过程只在创造时进行编译即可,以 ...
- javascript5
调用对象call object: 声明上下文对象declarative environment record; 作用域链scopechain: 变量解析:variable resolution: 引用 ...
- API接口开发简述示例
作为最流行的服务端语言PHP(PHP: Hypertext Preprocessor),在开发API方面,是很简单且极具优势的.API(Application Programming Interfac ...
- Javascript轮播 支持平滑和渐隐两种效果
Javascript轮播 支持平滑和渐隐两种效果 先上两种轮播效果:渐隐和移动 效果一:渐隐 1 2 3 4 效果二:移动 1 2 3 4 接下来,我们来大致说下整个轮播的思路: 一.先来看简单的 ...
- 编程乐趣:C#获取日期所在周、月份第一和最后一天
原文:编程乐趣:C#获取日期所在周.月份第一和最后一天 写了个小功能,需要用到以周为时间段,于是写了个获取周第一和最后一天的方法,获取月份的第一和最后一天就比较简单了.代码如下: public cla ...