背景

在之前的文章中《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. Retrofit:类型安全的REST客户端for 安卓&Java

    Retrofit:类型安全的REST客户端for 安卓&Java 2014年5月5日 星期一 21:11 官网:  http://square.github.io/retrofit/ GitH ...

  2. 1、量化投资—为什么选择Python?

    Python在量化领域的现状 就跟Java在web领域无可撼动的地位一样,Python也已经在金融量化投资领域占据了重要位置,从各个业务链条都能找到相应的框架实现. 在量化投资(证券和比特币)开源项目 ...

  3. 生成元(UVa1583)

    题目具体描述见:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_prob ...

  4. python脚本传入参数--精讲(getopt模块)

    1.最常用的sys.argv[],这个不多谈 2.形如 dahu@dahu-OptiPlex-:~/json_folder$ python sub1.py -abb -oaaa --output=ou ...

  5. mac如何运行vue项目

    由于本人使用的是mac系统,因此在vue.js 的环境搭建上遇到许许多多的坑.感谢 showonne.yubang 技术指导,最终成功解决.下面是个人的搭建过程,权当是做个笔记吧. 由于mac非常人性 ...

  6. 《java虚拟机》----java内存模型与线程

    No1. No2. java内存模型规定了所有的变量都存储在主内存中(Main Memory)中 每条线程还有自己的工作内存(Working Memory) 线程的工作内存中保存了被该线程使用到的变量 ...

  7. HDU 6029 Graph Theory

    贪心. 每次找到后面最近的一个能连边的连边. #include <bits/stdc++.h> using namespace std; ; int T,n,k; ],b[],u[]; i ...

  8. Python画一朵花

    from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm from matplotlib.ticker import Line ...

  9. Typora ---一款简洁的Markdown编辑器

    Typora BB in front 如果你是一个佛(lan)系(duo),内心文艺的程序员,并且你对其他Markdown编辑器的使用效果感觉不是很好的话,可以来了解一下该软件Typora. What ...

  10. 关于maven工程的几个BUG

    换了个新的环境,重新导入的maven工程出现了2个BUG: 1.Could not calculate build plan: Plugin org.apache.maven.plugins:mave ...