背景

在之前的文章中《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,但是多主键感觉真是不爽,两级还可以接受。

多主键映射这种风格可以导致“物理删除”,单主键这种风格可以导致“逻辑删除”。

如果是逻辑删除,需要注意哪些事项?

  1. 确定何时物理删除?如何物理删除?可以后台自动根据配置的元数据定时物理删除。
  2. 报表查询的时候注意查询语句。

为啥不用级联删除?

级联删除是解决:rep.delete(order),双主键是解决:order.OrderItems.Clear()。

备注

前几天我还暗自高兴找到了“物理删除”的映射方式,今天又更喜欢“逻辑删除”了,害苦了我一位兄弟,他都是用的 “双主键”。

EntityFramework:再谈 “如何映射聚合?”的更多相关文章

  1. Hibernate:如何映射聚合?

    Hibernate:如何映射聚合? 目录 背景映射聚合聚合模型映射配置测试备注 背景返回目录 DDD 是在 Hibernate 之后发现的概念,Hibernate 如何映射 DDD 中的聚合呢?本文给 ...

  2. 再谈angularJS数据绑定机制及背后原理—angularJS常见问题总结

    这篇是对angularJS的一些疑点回顾,是对目前angularJS开发的各种常见问题的整理汇总.如果对文中的题目全部了然于胸,觉得对整个angular框架应该掌握的七七八八了.希望志同道合的通知补充 ...

  3. 再谈HTTP2性能提升之背后原理—HTTP2历史解剖

    即使千辛万苦,还是把网站升级到http2了,遇坑如<phpcms v9站http升级到https加http2遇到到坑>. 因为理论相比于 HTTP 1.x ,在同时兼容 HTTP/1.1 ...

  4. 【字符串算法1】 再谈字符串Hash(优雅的暴力)

    [字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述  [字符串算法1] 字符串Hash 老版原文: RK哈希(Rabin_Ka ...

  5. 再谈JavaScript的数据类型问题

    JavaScript的数据类型问题已经讨论过很多次了,但许多人还有许多书仍然沿用着错误的.混乱的一些观点,所以就再细讲一回. 提及这个讨论的原因在于argb同学在我的MSN博客上的一段回复,又更早的起 ...

  6. 再谈Transaction——MySQL事务处理分析

    MySQL 事务基础概念/Definition of Transaction 事务(Transaction)是访问和更新数据库的程序执行单元;事务中可能包含一个或多个 sql 语句,这些语句要么都执行 ...

  7. [转载]再谈百度:KPI、无人机,以及一个必须给父母看的案例

    [转载]再谈百度:KPI.无人机,以及一个必须给父母看的案例 发表于 2016-03-15   |   0 Comments   |   阅读次数 33 原文: 再谈百度:KPI.无人机,以及一个必须 ...

  8. Support Vector Machine (3) : 再谈泛化误差(Generalization Error)

    目录 Support Vector Machine (1) : 简单SVM原理 Support Vector Machine (2) : Sequential Minimal Optimization ...

  9. Unity教程之再谈Unity中的优化技术

    这是从 Unity教程之再谈Unity中的优化技术 这篇文章里提取出来的一部分,这篇文章让我学到了挺多可能我应该知道却还没知道的知识,写的挺好的 优化几何体   这一步主要是为了针对性能瓶颈中的”顶点 ...

随机推荐

  1. POJ 3169 Layout (spfa+差分约束)

    题目链接:http://poj.org/problem?id=3169 题目大意:n头牛,按编号1~n从左往右排列,可以多头牛站在同一个点,给出ml行条件,每行三个数a b c表示dis[b]-dis ...

  2. Django之进阶相关操作

    一.QuerySet的特点 1.可切片 使用Python 的切片语法来限制查询集记录的数目 .它等同于SQL 的LIMIT 和OFFSET 子句. 1 >>> Entry.objec ...

  3. EasyUi–8.datebox赋值的问题

    这个问题要从EasyUI的datebox组件说起,小菜用这个组件的时候,发现用$("#id").val()这种形式,居然拿不到文本框的值! 经过度娘的帮助,发现可以用$(" ...

  4. fastdfs5.x Java客户端简单例子

    下载源码, 使用maven编译并安装 https://github.com/happyfish100/fastdfs-client-java.git 新建maven工程,引入fastdfs-clien ...

  5. IIS 部署nodejs

    1.Node.js 2.IIS的URL Rewrite模块 3.iisnode

  6. TeX中的引号(UVa272)

    问题: 在Tex中,做双引号的" `` ",右双引号是"  '' "(两个回车左边的).输入一篇包含双引号的文章,你的任务是把它转换成TeX的格式. 样例输入: ...

  7. lr11_Controller_Options选项介绍:

    lr11_Controller_Options选项介绍:

  8. 为什么主引导记录的内存地址是0x7C00?

    转自:http://www.ruanyifeng.com/blog/2015/09/0x7c00.html 当时,搭配的操作系统是86-DOS.这个操作系统需要的内存最少是32KB.我们知道,内存地址 ...

  9. braft初探

    接上一篇<brpc初探>. 什么是RAFT 看内部一个开源项目的时候,一开始我以为他们自己实现了raft协议.但是看了代码之后,发现用的是braft.因为在我们自己bg里一直在提paxos ...

  10. Jenkins多选项框使用

    多选框的使用场景还是挺多的,比如发布多个服务,或者选择哪些服务器 想要使用多选项,则需要安装插件extend choice parameter,然后在项目中配置参数化构建过程 配置完上面,我们就可以在 ...