[学习笔记]解决因C#8.0的语言特性导致EFCore实体类型映射的错误

news2024/11/20 13:40:17

今天下午在排查一个EF问题时,遇到了个很隐蔽的坑,特此记录。

问题

使用ef执行Insert对象到某表时报错,此对象的Address为空:

 不能将值 NULL 插入列 'Address',表 'dbo.xxx';列不允许有 Null 值。INSERT 失败。

检查数据库和迁移文件时发现Address这个字段被意外设置成nullable: false,而其它的字段却正常,按理来说对于string类型的属性,EFCore在codefirst模式下应该映射为可空类型。

代码也确认了实体中不包含[Required]注释,在任何地方也没有出现.IsRequired()的调用。

于是开始排查:手动创建一个空程序集,引用EFCore,从原项目拷贝EF设计时库、DbContext和各实体类,一顿操作后竟然发现在新的程序集中生成的迁移文件是符合预期的。
令人费解,在多次比对代码之后,发现是.csproj文件中的这一行配置导致的

<Nullable>enable</Nullable>

原因分析

C# 8 引入了一项名为可为 null 引用类型 (NRT) 的新功能。官方文档
该功能允许对引用类型进行批注,指示引用类型能否包含 null。

通过查看EF文档了解到,可为空引用类型通过以下方式影响 EF Core 的行为:

  • 如果禁用可为空引用类型,则按约定将具有 .NET 引用类型的所有属性配置为可选 (例如 string ) 。
  • 如果启用了可为 null 的引用类型,则基于属性的 .NET 类型的 C# 为 Null 性来配置属性:string? 将配置为可选属性,但 string 将配置为必需属性。

换而言之,启用了该功能后,把原本《引用类型可为空》的这个传统约定,更改称为了《引用类型是否可为空,是通过?语法来表明的》,实体中string类型的属性在C#中作为引用类型,自然而然地受到了这个影响。

果然,在删除了这个功能后,string?的语法将不起作用

在这里插入图片描述

解决

关闭此功能,重新生成迁移,更新数据库,问题解决。

后记

语言特性会影响EF实体与表结构映射的约定,官方示例中对于string类型的处理方式也做了说明:

无NRT


public class CustomerWithoutNullableReferenceTypes
{
    public int Id { get; set; }

    [Required] // Data annotations needed to configure as required
    public string FirstName { get; set; }

    [Required]
    public string LastName { get; set; } // Data annotations needed to configure as required

    public string MiddleName { get; set; } // Optional by convention
}

有NRT

public class Customer
{
    public int Id { get; set; }
    public string FirstName { get; set; } // Required by convention
    public string LastName { get; set; } // Required by convention
    public string? MiddleName { get; set; } // Optional by convention

    // Note the following use of constructor binding, which avoids compiled warnings
    // for uninitialized non-nullable properties.
    public Customer(string firstName, string lastName, string? middleName = null)
    {
        FirstName = firstName;
        LastName = lastName;
        MiddleName = middleName;
    }
}

这两种模型的数据库映射是等价的。

之后应留意项目的"NRT"功能是否开启,在解决方案.csproj文件中用如下方式关闭

<Nullable>disable</Nullable>

留意实体类中是否有代码段被标识"NRT"功能开启

#nullable disable

#nullable enable

从 .NET 6 开始,默认情况下会为新项目启用这些功能。原始项目是.NET 5.0升级而来的,所以项目文件中并不会包含Nullable相关的配置。

为了一行bug,好值得的一个下午呢

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

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

相关文章

基于云服务器的博客和靶场搭建-经验教训

搭这两个东西还是走了很多弯路 我就不给你们讲方法过程了&#xff0c;直接参考我给的链接&#xff0c;我主要说经验教训 博客搭建参考&#xff1a;https://zhuanlan.zhihu.com/p/37896471 靶场搭建参考&#xff1a;https://zhuanlan.zhihu.com/p/86409304 https://www.free…

LAMP搭建Discuz

文章目录 一、关闭防火墙二、安装apache三、安装Mysql四、安装PHP五、安装Discuz 一、关闭防火墙 [rootlocalhost ~]# systemctl status firewalld.service还要关闭selinux&#xff0c;要不然后面web页安装Discuz时会过不去。 [rootlocalhost ~]# setenforce 0编辑 /etc/seli…

堆排序——我欲修仙(功法篇)

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️我欲修仙】 学习名言&#xff1a;学习和研究好比爬梯子&#xff0c;要一步一步地往上爬&#xff0c;企图一脚跨上四五步&#xff0c;平地登天&#xff0c;那就必须会摔跤了。——华罗庚 系列文章目录…

国产游戏引擎,竟然用来搞民航

​本文源自量子位 | 公众号 QbitAI 只是给飞行员做个“装备”&#xff0c;竟然突破了国内民用航空领域的一大技术难题&#xff1f;&#xff01; 这是一群游戏技术开发者的真实经历。 他们用自研游戏引擎开发了一个飞行模拟软件&#xff0c;能够第一视角模拟飞行员起飞、着陆…

Html中使用jquery通过Ajax请求WebService接口以及跨域问题解决

场景 VS2019新建WebService/Web服务/asmx并通过IIS实现发布和调用&#xff1a; VS2019新建WebService/Web服务/asmx并通过IIS实现发布和调用_霸道流氓气质的博客-CSDN博客 在上面实现发布WebService的基础上&#xff0c;怎样在html中通过jquery对接口发起 请求和解析数据。…

【航空和卫星图像中检测建筑物】使用gabor特征和概率的城市区域和建筑物检测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

领域驱动设计DDD架构解析和绘图模板分享

DDD整洁架构 DDD整洁架构为了解决强调用的关系&#xff0c;出现了洋葱架构&#xff08;六边形&#xff09;架构&#xff0c;就是为了实现依赖倒置 它的思想就是把领域模型放到核心的位置&#xff0c;领域模型是独立的&#xff0c;不会直接强依赖其他层&#xff0c;而通过适配…

mmtrack mmdet mmcv环境安装 版本匹配 2023.5.18

一、参考官网&#xff1a; https://mmtracking.readthedocs.io/zh_CN/latest/install.html# mmtracking&#xff0c;mmcv&#xff0c;mmdetection版本匹配关系&#xff1a; MMTracking versionMMCV versionMMDetection versionmastermmcv-full>1.3.17, \<2.0.0MMDetec…

100 个 Go 错误以及如何避免:9~12

协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【OpenDocCN 饱和式翻译计划】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 真相一旦入眼&#xff0c;你就再也无法视而不见。——《黑客帝国》 九、并发实践 本章涵盖 防止 …

vue3的学习【超详细】

目录 一、vue3的优点1、vue3的优点 二、常用的API1、setup&#xff08;Composition API&#xff09;2、生命周期&#xff08;Composition API&#xff09;3、ref函数和reactive函数用法和区别&#xff08;Composition API&#xff09;1、ref2、reactive3、ref和reactive的区别 …

linux + ros 使用 catkin 从源码编译安装并运行 rocon_rtsp_camera_relay 订阅 rtsp 视频流

1. rocon_rtsp_camera_relay 介绍 最主要的功能在于把相机的 rtsp 视频流 转换为 ros topic 发布出来&#xff0c;使其他节点可以通过订阅的形式获取视频流数据。 2. 编译安装 注&#xff1a;官网的安装命令 sudo apt-get install ros-<distro>-rocon-rtsp-camera-rel…

leetcode 1557. Minimum Number of Vertices to Reach All Nodes(到达所有顶点的最少顶点集)

给出一个有向无环图&#xff08;DAG&#xff09;&#xff0c;顶点有n个&#xff1a;0&#xff5e;n - 1, 边[from, to]为从顶点from到to的边。 找出最小的顶点集合&#xff0c;从这些顶点出发能到达图中的所有顶点&#xff08;集合里不一定每个点都能到达所有顶点&#xff0c;而…

kettle——处理缺失值

目录 一、删除缺失值 1、文本文件输入 2、字段选择 3、过滤记录 4、输出excel文件 5、运行 二、填充缺失值 1、添加文件 2、过滤记录 3、替换NULL值 4、合并记录 5、替换NULL值2 6、字段选择 7、Excel输出 8、运行并查看执行结果 一、删除缺失值 1、文本文件输入…

MMOE - 经典多任务模型(谷歌)

文章目录 1、动机&#xff1a;2、模型结构&#xff1a; Modeling Task Relationships in Multi-task Learning with Multi-gate Mixture-of-Expertsmmoe: Multi-gate Mixture-of-Expertsmmoe由谷歌发表在KDD-2018【和阿里的ESMM同年发表&#xff0c;SIGIR-2018】&#xff1b;模…

华为手环8添加门禁卡操作指导

不得不说&#xff0c;华为基于手机/手环NFC和蓝牙等技术应用&#xff0c;结合门禁卡灵活、安全、便利的优势&#xff0c;给社区场景提供更优质和更多样的技术支持与服务&#xff0c;为广大用户创造美好的数字化生活体验。 目前华为手环8支持模拟市面上未经加密过的、频率为13.5…

服务发现原理与grpc源码解析

一 服务发现基础概念 为什么需要服务发现 在微服务架构中&#xff0c;在生产环境中服务提供方都是以集群的方式对外提供服务&#xff0c;集群中服务的IP随时都可能发生变化&#xff0c;如服务重启&#xff0c;发布&#xff0c;扩缩容等&#xff0c;因此我们需要及时获取到对应…

ThreadLocal使用和原理

ThreadLocal是线程本地变量&#xff0c;用来解决并发下数据隔离性的问题&#xff0c;不能解决共享。 他可以将一个变量拷贝的线程内&#xff0c;线程调用时再线程内进行使用&#xff0c;相当于给每个线程复制一个副本供各个线程使用。 ThreadLocal简单使用 他的目的很简单&a…

Unity用AI制作天空盒,并使用,详细图文教程

Unity用AI制作天空盒&#xff0c;并使用&#xff0c;详细图文教程 效果AI制作使用总结版权声明 效果 先上我自己做的效果 AI制作 首先登录AI制作的网站&#xff0c;打开就可以用&#xff0c;不需要登录 这是网址&#xff1a;https://skybox.blockadelabs.com/ 1.创建新的 2…

idea操作——如何format代码

1.选中需要format的类&#xff0c;然后右击&#xff0c;选择reformat code 2.出现的复选框根据自己的需求进行选择。然后点击OK即可。 Optimize imports 优化导入 选中此复选框可从所选范围内的代码中删除未使用的导入语句。 删除代码中没使用到的import 。使导入最优化 Rearr…

【C++】-模板初阶(函数和类模板)

作者&#xff1a;小树苗渴望变成参天大树 作者宣言&#xff1a;认真写好每一篇博客 作者gitee:gitee 作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 如 果 你 喜 欢 作 者 的 文 章 &#xff0c;就 给 作 者 点 点 关 注 吧&#xff01; 文章目录 前言一、为什么要模板&…