Asp.net core 学习笔记 ef core Surrogate Key, Natural Key, Alternate Keys
更新 : 2020-01-05
今天记入一下 alternate key 遇到的主次疑惑
alternate 会产生多个 foreignkey 的情况
比如我想选一个 state 那么前提是我要先选 country, 这样就需要有 2 个 foreignkey
所谓的主次疑惑是说在上面这个情况下我是要一个 state 所以当这个 state 换 country 后, 我也是要跟着它走的. 整个都是 cascade update.
另一种情况可能是我先选了一个 country, 然后我想再选一个 state, 这种情况下, country 是确定的. state 是依赖 country 的,
这时候如果 state 突然换了 country, 那么我其实是不想跟着换的,反而要阻止它,因为逻辑错了。
更新: 2019-12-23
在 ef 如果要拿不是 Id 来做 foreignkey 那么它就肯定是 alternative key 了,
当我们调用 HasPrincipalKey 这个时候 alternative key 就自动被做出来了。
在 sql 的话,其实并没有这么一个条件.
更新: 2019-11-01
虽然 Natural Key 很自然,但是维护起来成本很挺高
ef core 给了我们 Alternate Keys + composition
但是目前依然没有解决修改的问题
https://github.com/aspnet/EntityFrameworkCore/issues/4073

里面提到了使用 update cascade 的做法,虽然很不错,但是 sql server 的 cascade 不可以 multiple path
sql server 官方给出的意见是使用 trigger instand of
这个方法和 cascade 有很大区别的,正常情况下 cascade 的逻辑是交给子表,这种情况下扩展一个新的表是无需修改之前任何代码的。
但是如果使用了 trigger 就不得不把所有的逻辑放到一起了.
我们只能使用 trigger instand of 不可以使用 trigger after 因为 foreignkey 约束会直接报错而导致 delete 没有被执行,而 trigger 自然也不会触发了
所以只能使用 instand of, instand of 不是 before ,它的意思是替代,也就是说你得自己写过 delete 逻辑.
delete 尚可接受,但是 alternative key 需要 cascade update, 这个 update 语句可就不好写了..
目前我的做法是当遇到 cascade cycle 时, 把逻辑写在 application 而不交给 sql server trigger.
cascade update 手动维护需要暂时解开约束
类似
alter table People nocheck constraint FK_People_Countries;
update People set country = 'Singapore2' where country = 'Singapore';
update Countries set name = 'Singapore2' where name = 'Singapore';
alter table People with check check constraint FK_People_Countries;
更新: 2019-10-27
https://docs.microsoft.com/en-us/ef/core/modeling/relationships
https://docs.microsoft.com/en-us/ef/core/modeling/alternate-keys
composition alternate keys
有些时候 key 需要 2 个 column 才可以.比如很常见的 country, state
country 和 state 是 1-n 的关系
address 里需要记入 country and state
如果关系只是 country 1-n address 和 state 1-n address 的话
我们就无法确保, state 是 under country 的
这个时候就可以用 composition alternate keys 了
modelBuilder.Entity<Country>().HasAlternateKey(p => p.name);
modelBuilder.Entity<Country>().HasMany(p => p.states).WithOne(p => p.country).HasForeignKey(p => p.countryKey).HasPrincipalKey(p => p.name).OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Country>().Property(p => p.name).IsRequired(true).HasMaxLength();
modelBuilder.Entity<Country>().HasMany(p => p.people).WithOne(p => p.country)
.HasForeignKey(p => p.countryKey)
.HasPrincipalKey(p => new { p.name }).OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity<State>().HasAlternateKey(p => new { p.countryKey, p.name });
modelBuilder.Entity<State>().Property(p => p.name).IsRequired(true).HasMaxLength();
modelBuilder.Entity<State>().HasMany(p => p.people).WithOne(p => p.state)
.HasForeignKey(p => new { p.countryKey, p.stateKey })
.HasPrincipalKey(p => new { p.countryKey, p.name });
Surrogate Key vs Natural Key, 争论多年
2 个都有好处坏处.
ef core 对 Natural Key 支持比较弱.
使用 Alternate Keys 来实现
https://docs.microsoft.com/en-us/ef/core/modeling/alternate-keys
它最糟糕的地方是,目前不支持修改
https://stackoverflow.com/questions/36200436/cannot-update-alternate-key-entity-framework-core-1-0
https://github.com/aspnet/EntityFrameworkCore/issues/4073
对我来说大部分情况下 Surrogate Key 是好用的
但它凡事都要 join 表比较麻烦, filter 也好,查询值也好,都一定要 join.
所以我认为 Natural Key 只在一种情况下特别好
join 的 table 只是一个 primary column
比如有个 category 和 product
category 只有一个 name, 如果做一个 category 表那每次 product 就得 join category 为了拿唯一的 category name。
而如果 product 直接记入 category name 就方便多了.
短期内 ef 应该是不会支持 update 这个功能的,saveChanges 就报错说不能 edit 了,
目前的 workaround 是去 override migration 生成出来的 file 添加 onUpdate cascade,
table.ForeignKey(
name: "FK_Products_Categories_categoryName",
column: x => x.categoryName,
principalTable: "Categories",
principalColumn: "name",
onDelete: ReferentialAction.Restrict,
onUpdate: ReferentialAction.Cascade);
然后更新的时候直接调用语句.
var commandText = "update Categories set name = @categoryName where Id = @Id";
var categoryName = new SqlParameter("@categoryName", "man");
var Id = new SqlParameter("@Id", );
var ok = Db.Database.ExecuteSqlCommand(commandText, new[] { categoryName, Id });
Asp.net core 学习笔记 ef core Surrogate Key, Natural Key, Alternate Keys的更多相关文章
- Asp.net core 学习笔记 ( ef core )
更新 : 2018-11-26 这里记入一下关于 foreignKey cascade action 默认情况下如果我们使用 data annotation required + foreginkey ...
- Asp.net core 学习笔记 ( ef core transaction scope & change level )
ef core 有 unit of work 的概念,当我们 save change 时会自动使用 transaction 确保更新的一致性. 隔离级别是默认的 read committed 不允许脏 ...
- Asp.Net Core学习笔记:入门篇
Asp.Net Core 学习 基于.Net Core 2.2版本的学习笔记. 常识 像Django那样自动检查代码更新,自动重载服务器(太方便了) dotnet watch run 托管设置 设置项 ...
- .NET CORE学习笔记系列(2)——依赖注入[6]: .NET Core DI框架[编程体验]
原文https://www.cnblogs.com/artech/p/net-core-di-06.html 毫不夸张地说,整个ASP.NET Core框架是建立在一个依赖注入框架之上的,它在应用启动 ...
- .NET CORE学习笔记系列(2)——依赖注入【3】依赖注入模式
原文:https://www.cnblogs.com/artech/p/net-core-di-03.html IoC主要体现了这样一种设计思想:通过将一组通用流程的控制权从应用转移到框架中以实现对流 ...
- .NET CORE学习笔记系列(2)——依赖注入【1】控制反转IOC
原文:https://www.cnblogs.com/artech/p/net-core-di-01.html 一.流程控制的反转 IoC的全名Inverse of Control,翻译成中文就是“控 ...
- .NET CORE学习笔记系列(2)——依赖注入[7]: .NET Core DI框架[服务注册]
原文https://www.cnblogs.com/artech/p/net-core-di-07.html 包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IS ...
- .NET CORE学习笔记系列(2)——依赖注入[5]: 创建一个简易版的DI框架[下篇]
为了让读者朋友们能够对.NET Core DI框架的实现原理具有一个深刻而认识,我们采用与之类似的设计构架了一个名为Cat的DI框架.在上篇中我们介绍了Cat的基本编程模式,接下来我们就来聊聊Cat的 ...
- .NET CORE学习笔记系列(2)——依赖注入[4]: 创建一个简易版的DI框架[上篇]
原文https://www.cnblogs.com/artech/p/net-core-di-04.html 本系列文章旨在剖析.NET Core的依赖注入框架的实现原理,到目前为止我们通过三篇文章从 ...
随机推荐
- jeecg中获取用户拥有的角色的数据权限
String roles1=""; String sql=""; //1.获取用户 TSUser user = ResourceUtil.getSessionU ...
- Python排序算法之选择排序定义与用法示例
Python排序算法之选择排序定义与用法示例 这篇文章主要介绍了Python排序算法之选择排序定义与用法,简单描述了选择排序的功能.原理,并结合实例形式分析了Python定义与使用选择排序的相关操作技 ...
- 使用dd命令克隆整个Linux系统
参考:https://www.cnblogs.com/jikexianfeng/p/6103504.html 本次使用使用dd命令克隆整个Ubuntu系统 1,VM安装一台Ubuntu虚拟机 过程不详 ...
- AJAX的个人见解
ajax是什么? 在学习的过程中,我虽然在学习ajax但是对ajax的具体的意义不甚了解,对此我们就来看看什么ajax吧. Ajax的全称是:AsynchronousJavaScript+XML 2. ...
- iOS-保存图片到相册
//保存 UIButton *saveBtn = [[UIButton alloc] init]; // saveBtn.frame = CGRectMake((screenWi ...
- Tomcat 目录结构
bin目录主要是用来存放tomcat的命令,主要有两大类,一类是以.sh结尾的(linux命令),另一类是以.bat结尾的(windows命令). 很多环境变量的设置都在此处,例如可以设置JDK路径. ...
- Windows安装zabbix-agent4.0
1.在Windows系统中的C盘,新建一个zabbix目录C:/zabbix2.先下载zabbix-agent的安装包https://assets.zabbix.com/downloads/4.0.1 ...
- eNSP——交换机基础配置
原理: 交换机之间通过以太网电接口对接时需要协商一-些接口参数, 比如速率.双工模式等.交换机的全双工是指交换机在发送数据的同时也能够接收数据,两者同时进行.就如平时打电话一样,说话的同时也能够听到对 ...
- 连接池和JDBCTemplate
一:什么是连接池?使用连接池的好处是什么? 连接池就是一个存放数据库连接对象的容器.当系统初始化后,就会向数据库申请一些连接对象存放到容器里,用的时候直接从容器里取,用完后放回连接池. 连接池可以提高 ...
- 前端手势控制图片插件书写二(transform矩阵的原理)
上次解释了如何使用代码识别双指和单指操作及放大和旋转拖动操作.这次解释下css3的transform原理 一.transform矩阵原理 transform: matrix(a,b,c,d,e,f) ...