EntityFramework Core 迁移忽略主外键关系

【导读】本文来源于一位公众号童鞋私信我的问题,在我稍加思索后给出了如下一种方案,在此之前我也思考过这个问题,借此机会我稍微看了下,目前能够想到的也只是本文所述方案。

为何要忽略主外键关系

我们不仅疑惑为何要忽略主外键关系呢?不难想到,相对于大型企业而言大部分都会采用不建立主外键关系(简称,外键约束),外键约束毫无疑问维护了数据一致性,但对其进行操作时很容易造成问题,级联删除只是其一。

如果对于经常需要操作的表建立了外键约束,那么会严重影响插入、删除和更新的性能,因为在执行这些操作之前,数据库需要检查其是否违反数据完整性,这也就是为何大多数不管是DBA或者架构师完全放弃使用外键约束的原因,在分析数据库,它们并不能以事务方式(一次一行)来处理数据,而是批量处理,性能是一切,这是其二。

随着业务需求变化在设计数据库时,可能需要存储历史数据库中的旧数据,而这些旧数据可能对数据质量和完整性没有严格要求。为了能够容纳旧的脏数据,可直接清理和转换旧数据,而放弃在数据库级别上强制执行参照完整性,这是其三。

所以基于以上几点理由,忽略外键约束是有其原因所在,当然,是否放弃外键约束,可能取决于架构师或者DBA,反正决策权不在于搬砖的我们,我们知道其原因就好。

示例程序

以下示例皆在控制台中进行,老规矩,我们先给出示例模型,依然是Blog和Post两个实体,如下:

public class Blog
{public int Id { get; set; }public string Name { get; set; }public List<Post> Posts { get; set; }
}public class Post
{public int Id { get; set; }public string Title { get; set; }public int BlogId { get; set; }public Blog Blog { get; set; }
}

接下来则是定义上下文,如下:

public class EFCoreDbContext : DbContext
{public DbSet<Blog> Blogs { get; set; }public DbSet<Post> Posts { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){optionsBuilder.UseSqlServer("Server=.;Database=EFCore;Trusted_Connection=True;");}
}

忽略外键约束

上述即使我们没有显式通过注解或Fluent APi配置关系,但是会根据约定而发现其关系,所以最终会建立外键约束,那么我们怎么才能在迁移时不建立外键约束呢?对依赖实体通过注解显式配置不映射,如下:

[NotMapped]
public List<Post> Posts { get; set; }

请注意,这里必须是对依赖实体进行显式注解不映射,若是对依赖实体上的主体导航属性配置依然会生成外键约束,若是对外键进行注解不映射也是同理,只不过生成的外键名称和默认的外键名称不一样而已。

很显然,进行如上不建立外键约束后,当我们通过主体添加依赖体数据时将不会持久化到表中,比如如下通过Blog添加Posts

var context = new EFCoreDbContext();context.Add(new Blog()
{Name = "Jeffcky",Posts = new List<Post>(){new Post(){Title = "EntityFramework Core"}}
});var effectedRows = context.SaveChanges();

同理,当通过主体进行饥饿加载时将会抛出异常(无论是lambda表达式或字符串),比如如下,因为二者已经没有任何关联关系

var blog = context.Blogs.Include(d => d.Posts).FirstOrDefault(d => d.Id == 1);


基于上述,似乎没有什么很好的方式,只能采用最原始方式生成外键约束后,在迁移类中删除外键约束或数据库表手动删除外键约束,这样仍然可以很好的使用饥饿加载导航属性。

一旦实体比较多,手动删除又显得比较麻烦,我们可以写个程序,当迁移完毕后删除数据库表所有外键,如下截取删除外键的代码片段,不知是否行得通,理论上应该是可以实现的。

    public static class RemoveForeignKeyExetension{public static ModelBuilder RemoveForeignKeys(this ModelBuilder modelBuilder){var entityTypes = modelBuilder.Model.GetEntityTypes().ToList();for (int i = 0; i < entityTypes.Count(); i++){var entityType = entityTypes[i];var references = entityType.GetDeclaredReferencingForeignKeys().ToList();using (((Model)entityType.Model).Builder.Metadata.ConventionDispatcher.DelayConventions()){foreach (var reference in references){reference.DeclaringEntityType.RemoveForeignKey(reference);}}}return modelBuilder;}}

忽略外键约束(SQLite)

上述是针对SQL Server所做的测试,理论上MySQL同理,但对于SQLite数据库,EF Core 3.x提供了全局方案:通过数据连接字符串配置【Foreign Keys = False】全局抑制建立外键约束。

optionsBuilder.UseSqlite("Database=sqlite.db;Foreign Keys=False");

官方团队好像并未提供针对SQL Server或MySQL忽略而不建立外键约束而可以加载导航属性的办法,只能采取笨拙或者如上所述写个程序去删除外键约束或者通过注解方式实现,但是一旦使用注解将无法加载导航属性,那么用EF Core就失去了很大的意义,我认为

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309037.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你很可能需要知道这个调试小技巧

缘起 最近在调试的时候&#xff0c;需要观察第三方容器中每一个元素的值。默认情况下&#xff0c;vs 并不知道如何显示第三方容器的内容&#xff0c;只能手动观察容器中的每一个值&#xff0c;超级不方便。我找到一个非常给力的好办法&#xff0c;你还知道其它好办法吗&#xf…

全宇宙首本 VS Code 中文书,来了!

大家好&#xff01;我是韩骏&#xff0c;VS Code 中文社区创始人&#xff0c;VS Code 的代码贡献者。2013 年&#xff0c;毕业于上海交通大学软件学院&#xff0c;现在是微软开发平台事业部的软件工程师。写过 20 多款 VS Code 插件&#xff0c;其中最热门的 Code Runner 插件有…

C# 从1到Core--委托与事件

委托与事件在C#1.0的时候就有了&#xff0c;随着C#版本的不断更新&#xff0c;有些写法和功能也在不断改变。本文温故一下这些改变&#xff0c;以及在NET Core中关于事件的一点改变。一、C#1.0 从委托开始1. 基本方式什么是委托&#xff0c;就不说概念了&#xff0c;用例子说话…

开源导入导出库Magicodes.IE 多sheet导入教程

多Sheet导入教程说明本教程主要说明如何使用Magicodes.IE.Excel完成多个Sheet数据的Excel导入。要点多个相同格式的Sheet数据导入多个不同格式的Sheet数据导入主要步骤1. 多个相同格式的Sheet数据导入1.1 创建导入Sheet的Dto主要代码如下所示&#xff1a;学生数据Dto/// <su…

解决 Azure AD 在 Azure Front Door 下登录失败的问题

点击上方关注“汪宇杰博客” ^_^导语最近我给博客系统加上了 Azure Front Door&#xff0c;集齐了12项 Azure 服务打算召唤神龙。没想到刚上线&#xff0c;Azure AD 的单点登录就爆了。OIDC 跳转错误当我尝试登录博客后台的时候&#xff0c;OIDC的跳转URL突然变成了 https://ed…

《Unit Testing》2.1 经典学派如何做测试隔离

经典学派如何解决隔离问题首先&#xff0c;再回顾一下单元测试的三个重要特性&#xff1a;验证一小段代码&#xff08;或者叫一个单元&#xff09;执行速度快使用隔离的方式进行针对第一个特性就会引出一个问题&#xff1a;多小的一段代码才足够小&#xff1f;如果你采用针对每…

Hacker News热文:请停止学习框架,学习领域驱动设计(DDD)(获500个点赞)

在 Hacker News 上获得接近 500 个点赞的一篇名为《停止学习框架》的文章称&#xff1a;我们是程序员&#xff0c;每天都在了解最新的技术&#xff0c;每天都在学习编程语言、框架和库&#xff0c;因为我们知道的现代编程工具越多越好&#xff0c;对吧&#xff1f;不停地追随 A…

C#跨平台开源项目实战(WPF/Android/IOS/Blazor)

个人介绍由于本人从业WPF开发, 考虑到国内的WPF开发环境并不是很好, 资源少、项目案例少, 所以导致很多初学者就已经断了念头。所以我作为WPF的从业者, 就在2019年,开始了发布自己的WPF相关的免费教学视频。发布开源的项目实践, WPF的基础视频、项目实践视频, 包括WPF UI设计视…

[开源] .Net 使用 ORM 访问 神舟通用数据库(神通)

前言天津神舟通用数据技术有限公司&#xff08;简称“神舟通用公司”&#xff09;&#xff0c;隶属于中国航天科技集团&#xff08;CASC&#xff09;。是国内从事数据库、大数据解决方案和数据挖掘分析产品研发的专业公司。公司获得了国家核高基科技重大专项重点支持&#xff0…

在 Xunit 中使用依赖注入

在 Xunit 中使用依赖注入Intro之前写过一篇 xunit 的依赖注入相关的文章&#xff0c;但是实际使用起来不是那么方便今天介绍一个基于xunit和微软依赖注入框架的“真正”的依赖注入使用方式 ——— Xunit.DependencyInjection, 来自大师的作品&#xff0c;让你在测试代码里使用依…

C#由转换二进制所引起的思考,了解下?

【导读】最近遇到很有意思转换二进制的问题&#xff0c;有部分童鞋俨然已了解&#xff0c;可能也有一部分童鞋没碰到过也就不知情&#xff0c;这里我们来深入学习下转换二进制所带来的问题。在写此篇文章时&#xff0c;非常开心&#xff0c;收到再一次连任MVP的邮件&#xff0c…

.Net Core In Docker 在容器内编译并发布

Docker可以说是现在微服务&#xff0c;DevOps的基础&#xff0c;咱们.Net Core自然也得上Docker。.Net Core发布到Docker容器的教程网上也有不少&#xff0c;但是今天还是想来写一写。你搜.Net core程序发布到Docker网上一般常见的有两种方案&#xff1a;1、在本地编译成Dll文件…

带你深入探究云原生时代的分布式操作系统 Kubernetes

过去几年&#xff0c;以 docker、kubernetes 为代表的容器技术已发展为一项通用技术&#xff0c;BAT、滴滴、京东、头条等大厂&#xff0c;都争相把容器和 k8s 项目作为技术重心&#xff0c;试图“放长线钓大鱼”。就说腾讯吧&#xff0c;目前基本所有业务都跑在云上&#xff0…

C# 9.0 新特性之 Lambda 弃元参数

阅读本文大概需要不到 1 分钟。弃元&#xff08;Discards&#xff09; 是在 C# 7.0 的时候开始支持的&#xff0c;它是一种人为丢弃不使用的临时虚拟变量。语法上它是用来赋值的&#xff0c;但它却不被分配存储空间&#xff0c;即没有值&#xff0c;所以不能从中读取值。弃元用…

应用交付老兵眼中的Envoy, 云原生时代下的思考

Envoy 是云原生时代的明星&#xff0c;其本质是反向代理负载均衡类软件&#xff0c;领域上归于应用交付&#xff0c;那么作为应用交付领域的老兵如何看待 Envoy&#xff0c;Envoy 又引发了哪些关于传统应用交付领域的思考&#xff1f;关于作者林静&#xff0c;F5 软件方向解决方…

asp.net core程序在k8s中基于rabbitmq队列消息数的HPA实践!

背景最近一段时间&#xff0c;陆陆续续的把手里头项目都迁移到了k8s中&#xff0c;期间遇到很多的坑&#xff0c;并且也学到了许多k8s的知识&#xff08;从0-1&#xff09;&#xff0c;大家都知道k8s中的一大特性是自动扩容&#xff0c;对此结合自己的业务发现很是有“用武之地…

如何优雅做系统错误提示?

这里是Z哥的个人公众号每周五11&#xff1a;45 按时送达当然了&#xff0c;也会时不时加个餐&#xff5e;我的第「149」篇原创敬上大家好&#xff0c;我是Z哥。不管是日常的工作中还是生活中&#xff0c;我们每天会用到很多软件系统。不知道你有没有过这样的感受&#xff0c;当…

搭建一套ASP.NET Core+Nacos+Spring Cloud Gateway项目

前言伴随着随着微服务概念的不断盛行&#xff0c;与之对应的各种解决方案也层出不穷。这毕竟是一个信息大爆发的时代&#xff0c;各种编程语言大行其道&#xff0c;各有各的优势。但是有一点未曾改变&#xff0c;那就是他们服务的方式&#xff0c;工作的时候各司其职&#xff0…

如何在ASP.NET Core中集成ElasticSearch

本文来自&#xff1a;https://www.blexin.com/en-US/Article/Blog/How-to-integrate-ElasticSearch-in-ASPNET-Core-70图片我敢打赌&#xff0c;您肯定会被要求向Web应用程序中添加高级搜索功能&#xff0c;而且通常是全文的类似Google的搜索。在技术电子商务的开发过程中&…

了解下C#由转换二进制所引起的思考

【导读】最近遇到很有意思转换二进制的问题&#xff0c;有部分童鞋俨然已了解&#xff0c;可能也有一部分童鞋没碰到过也就不知情&#xff0c;这里我们来深入学习下转换二进制所带来的问题。在写此篇文章时&#xff0c;非常开心&#xff0c;收到再一次连任MVP的邮件&#xff0c…