使用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发送邮件的方式.所以这里涉及到四块内容 ...
随机推荐
- mysql_oracle_随机查询几条记录
数据库的随机查询SQL 1. Oracle,随机查询20条 select * from ( select * from 表名 order by dbms_random.value ) where ...
- oracle_查询Oracle正在执行和执行过的SQL语句
---正在执行的select a.username, a.sid,b.SQL_TEXT, b.SQL_FULLTEXT from v$session a, v$sqlarea b where a.s ...
- 【百度地图API】多家地图API文件大小对比
原文:[百度地图API]多家地图API文件大小对比 于2011.6.9日更新百度地图API文件大小.同时更新图片. 任务描述: 明天就是元宵佳节啦~这是一个团团圆圆的节日,于是,再次想把各家API聚在 ...
- bootstrap collapse MVC .net漂亮的折叠List
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta na ...
- IBM BigInsights 3.0.0.2 集群环境搭建
1. 改动hosts文件和永久主机名 由于BigInsights 3.0版本号不像之前的版本号能够直接用IP来添加节点,因此我们须要更改每台server的hosts文件和主机名: vim/etc/ho ...
- 创建GitHub技术博客
创建GitHub技术博客全攻略 githubio技术博客网站生成 说明: 首先,你需要注册一个 github 账号,最好取一个有意义的名字,比如姓名全拼,昵称全拼,如果被占用,可以加上有意义的数字.本 ...
- ubuntu eclipse android搭建
1.eclipse加入android adt: 终端:sudo gedit /etc/hosts 加入: #for android 173.194.72.93 dl.google.com 173.19 ...
- 单元测试之Qunit
单元测试之Qunit 前言 因为公司开发了一套javascript SDK需要测试,在网上找了很久,找到了JQuery团队开发的QUnit,和基于JUnit的JsUnit,还有一些还没有看,先讲讲QU ...
- Java 实现迭代器(Iterator)模式
类图 /** * 自己定义集合接口, 相似java.util.Collection * 用于数据存储 * @author stone * */ public interface ICollection ...
- C语言字符串操作函数集
1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, p1) 附加字符串 strncat(p, p1, n) 附加指定长度 ...