EntityFramework:再谈 “如何映射聚合?”
背景
在之前的文章中《DDD:使用EntityFramework的话,如果只为聚合根设计仓储,其它实体如何处理?》,我介绍了如何映射聚合以保证其语义,当时的结论是:聚合内除了聚合根之外的实体必须使用多主键,否则删除操作(Order.OrderItems.Remove(1))只会将外键更新为 Null,最开始学习如何使用 EntityFramework 来映射聚合的时候,就纠结这个问题,当时汤雪华大哥就告诉了更新为 Null 就算删除了,当时感觉是接受了,不过没有内化,这篇文章也是为了内化这种思想。
使用多主键映射三级聚合
模型
public class Level1
{
public virtual int Level1Id { get; set; } public virtual ICollection<Level2> Level2s { get; set; }
} public class Level2
{
public virtual int Level2Id { get; set; }
public virtual int Level1Id { get; set; } public virtual ICollection<Level3> Level3s { get; set; }
} public class Level3
{
public virtual int Level3Id { get; set; }
public virtual int Level2Id { get; set; }
public virtual int Level1Id { get; set; }
}
映射
modelBuilder.Entity<Level1>()
.HasKey(x => x.Level1Id)
.Property(x => x.Level1Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Level1>()
.HasMany(x => x.Level2s)
.WithRequired()
.HasForeignKey(x => x.Level1Id)
.WillCascadeOnDelete(); modelBuilder.Entity<Level2>()
.HasKey(x => new { x.Level2Id, x.Level1Id })
.Property(x => x.Level2Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Level2>()
.HasMany(x => x.Level3s)
.WithRequired()
.HasForeignKey(x => new { x.Level2Id, x.Level1Id })
.WillCascadeOnDelete(); modelBuilder.Entity<Level3>()
.HasKey(x => new { x.Level3Id, x.Level2Id, x.Level1Id })
.Property(x => x.Level3Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
测试添加
for (var i = ; i <= ; i++)
{
var l1 = new Level1
{
Level2s = new List<Level2>
{
new Level2
{
Level3s = new List<Level3>
{
new Level3()
}
}
}
};
context.Level1s.Add(l1);
context.SaveChanges();
}
测试删除
using (var context = new StudyContext())
{
context.Level1s.First().Level2s.First().Level3s.Clear(); context.SaveChanges();
}
说明
因为采用了多主键,所以 context.Level1s.First().Level2s.First().Level3s.Clear() 会真正的生成 delete 语句,否则只会把外键更新为 null,但是多主键感觉真是不爽,两级还可以接受。
多主键映射这种风格可以导致“物理删除”,单主键这种风格可以导致“逻辑删除”。
如果是逻辑删除,需要注意哪些事项?
- 确定何时物理删除?如何物理删除?可以后台自动根据配置的元数据定时物理删除。
- 报表查询的时候注意查询语句。
为啥不用级联删除?
级联删除是解决:rep.delete(order),双主键是解决:order.OrderItems.Clear()。
备注
前几天我还暗自高兴找到了“物理删除”的映射方式,今天又更喜欢“逻辑删除”了,害苦了我一位兄弟,他都是用的 “双主键”。
EntityFramework:再谈 “如何映射聚合?”的更多相关文章
- Hibernate:如何映射聚合?
Hibernate:如何映射聚合? 目录 背景映射聚合聚合模型映射配置测试备注 背景返回目录 DDD 是在 Hibernate 之后发现的概念,Hibernate 如何映射 DDD 中的聚合呢?本文给 ...
- 再谈angularJS数据绑定机制及背后原理—angularJS常见问题总结
这篇是对angularJS的一些疑点回顾,是对目前angularJS开发的各种常见问题的整理汇总.如果对文中的题目全部了然于胸,觉得对整个angular框架应该掌握的七七八八了.希望志同道合的通知补充 ...
- 再谈HTTP2性能提升之背后原理—HTTP2历史解剖
即使千辛万苦,还是把网站升级到http2了,遇坑如<phpcms v9站http升级到https加http2遇到到坑>. 因为理论相比于 HTTP 1.x ,在同时兼容 HTTP/1.1 ...
- 【字符串算法1】 再谈字符串Hash(优雅的暴力)
[字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述 [字符串算法1] 字符串Hash 老版原文: RK哈希(Rabin_Ka ...
- 再谈JavaScript的数据类型问题
JavaScript的数据类型问题已经讨论过很多次了,但许多人还有许多书仍然沿用着错误的.混乱的一些观点,所以就再细讲一回. 提及这个讨论的原因在于argb同学在我的MSN博客上的一段回复,又更早的起 ...
- 再谈Transaction——MySQL事务处理分析
MySQL 事务基础概念/Definition of Transaction 事务(Transaction)是访问和更新数据库的程序执行单元;事务中可能包含一个或多个 sql 语句,这些语句要么都执行 ...
- [转载]再谈百度:KPI、无人机,以及一个必须给父母看的案例
[转载]再谈百度:KPI.无人机,以及一个必须给父母看的案例 发表于 2016-03-15 | 0 Comments | 阅读次数 33 原文: 再谈百度:KPI.无人机,以及一个必须 ...
- Support Vector Machine (3) : 再谈泛化误差(Generalization Error)
目录 Support Vector Machine (1) : 简单SVM原理 Support Vector Machine (2) : Sequential Minimal Optimization ...
- Unity教程之再谈Unity中的优化技术
这是从 Unity教程之再谈Unity中的优化技术 这篇文章里提取出来的一部分,这篇文章让我学到了挺多可能我应该知道却还没知道的知识,写的挺好的 优化几何体 这一步主要是为了针对性能瓶颈中的”顶点 ...
随机推荐
- POJ 3169 Layout (spfa+差分约束)
题目链接:http://poj.org/problem?id=3169 题目大意:n头牛,按编号1~n从左往右排列,可以多头牛站在同一个点,给出ml行条件,每行三个数a b c表示dis[b]-dis ...
- Django之进阶相关操作
一.QuerySet的特点 1.可切片 使用Python 的切片语法来限制查询集记录的数目 .它等同于SQL 的LIMIT 和OFFSET 子句. 1 >>> Entry.objec ...
- EasyUi–8.datebox赋值的问题
这个问题要从EasyUI的datebox组件说起,小菜用这个组件的时候,发现用$("#id").val()这种形式,居然拿不到文本框的值! 经过度娘的帮助,发现可以用$(" ...
- fastdfs5.x Java客户端简单例子
下载源码, 使用maven编译并安装 https://github.com/happyfish100/fastdfs-client-java.git 新建maven工程,引入fastdfs-clien ...
- IIS 部署nodejs
1.Node.js 2.IIS的URL Rewrite模块 3.iisnode
- TeX中的引号(UVa272)
问题: 在Tex中,做双引号的" `` ",右双引号是" '' "(两个回车左边的).输入一篇包含双引号的文章,你的任务是把它转换成TeX的格式. 样例输入: ...
- lr11_Controller_Options选项介绍:
lr11_Controller_Options选项介绍:
- 为什么主引导记录的内存地址是0x7C00?
转自:http://www.ruanyifeng.com/blog/2015/09/0x7c00.html 当时,搭配的操作系统是86-DOS.这个操作系统需要的内存最少是32KB.我们知道,内存地址 ...
- braft初探
接上一篇<brpc初探>. 什么是RAFT 看内部一个开源项目的时候,一开始我以为他们自己实现了raft协议.但是看了代码之后,发现用的是braft.因为在我们自己bg里一直在提paxos ...
- Jenkins多选项框使用
多选框的使用场景还是挺多的,比如发布多个服务,或者选择哪些服务器 想要使用多选项,则需要安装插件extend choice parameter,然后在项目中配置参数化构建过程 配置完上面,我们就可以在 ...