使用 C# 9 的records作为强类型ID - 初次使用

强类型ID

实体通常是整数,GUID或者string类型,因为数据库直接支持这些类型,但是,如果实体的ID的类型是一样的,比如都是整数的ID,这有可能会出现ID值传错的问题,看下边的示例。

public void AddProductToOrder(int orderId, int productId, int count)
{...
}...// 这个地方,参数传错了
AddProductToOrder(productId, orderId, int count);

上面的代码可以很好地通过检查并编译,但是在运行的时候就出问题了,这是逻辑bug。

幸运的是,可以定义强类型id来解决这个问题,这个想法很简单,为每个实体的ID声明一个特定的类型,现在需要这样写:

// 使用强类型ID代替整数ID
public void AddProductToOrder(OrderId orderId, ProductId productId, int count)
{...
}...// 这个地方,参数传错了
AddProductToOrder(productId, orderId, int count);

在上面的代码中,我们犯了与第一个示例相同的错误(交换productId和orderId),但是在这种情况下,类型不同,因此编译器会捕获该错误并报告错误,我们仍然需要对其进行修复,但是至少在生产中并没有爆炸。

编写一个强类型的id

public readonly struct ProductId : IEquatable<ProductId>
{public ProductId(int value){Value = value;}public int Value { get; }public bool Equals(ProductId other) => other.Value == Value;public override bool Equals(object obj) => obj is ProductId other && Equals(other);public override int GetHashCode() => Value.GetHashCode();public override string ToString() => $"ProductId {Value}";public static bool operator ==(ProductId a, ProductId b) => a.Equals(b);public static bool operator !=(ProductId a, ProductId b) => !a.Equals(b);
}

上面的代码没什么难的,但是如果每个实体都需要的话,那确实有点麻烦,在C# 9 可以使用source generators来完成这些,但是C# 9还引入了另一个功能,使用起来更方便。

Record类型

Record 类型是具有内置不变性和值语义的引用类型,它和上面我们写的强类型是一样的(手动写的成员实现Equals,GetHashCode等等),在代码中使用也非常简洁, 如果我们ProductId使用record重写类型,就是下边这样:

public record ProductId(int Value);

是的,您没看错,这是一行,而上面的代码是一大段,它完成了我们手动执行的所有操作(实际上,还多了很多!)。

主要区别在于:我们的手动实现是struct,即值类型,但是记录是引用类型,这意味着它们可以为null,这可能不是主要问题,尤其是在使用可为空的引用类型的情况下,但是要知道这一点。

现在为模型中的每个实体编写一个强类型的id是不是很简单,使用Record 非常方便,当然,还有其他问题需要考虑,例如JSON序列化,与Entity Framework Core一起使用等,但这是另一篇文章的故事!

最后

欢迎扫码关注我们的公众号 【全球技术精选】,专注国外优秀博客的翻译和开源项目分享,也可以添加QQ群 897216102

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

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

相关文章

linux配置文件引用时间,linux时间设置、screen使用、命令分类、hash作用、命令引用及history命令...

一、 生产环境发现一台服务器系统时间产生偏差&#xff0c;造成服务异常解决方法a、 如果服务器硬件时间准备的话&#xff0c;可使用命令&#xff1a;~#] hwclock -s将硬件时钟同步到系统b、date [MMDDhhmm[[CC]YY][.ss]] 分别为&#xff1a;月日小时分年.秒eg:~]# date 101420…

用拖拉实现设备驱动配置(EsayHMI最新驱动配置方式)

以前的IOServer 是用VB6开发&#xff0c;驱动的配置方式和一般的组态软件没有什么很大的区别&#xff0c;配置起来比较麻烦&#xff0c;对一般的生手来说&#xff0c;要费一番功夫才能配置完毕。 总觉得原有的程序和目前的HMI图元配置环境格格不入&#xff0c;所以重新编写了驱…

HttpClientFactory 结合 Polly 轻松实现重试机制

HttpClientFactory 结合 Polly 轻松实现重试机制Intro我们的服务里有一个 API 会去调用第三方的接口&#xff0c;设置了超时时间&#xff0c;最近偶尔会发生超时的情况&#xff0c;微软在提供 HttpClientFactory 的同时&#xff0c;也提供了一个基于 Polly 的一个扩展&#xff…

ASP.NET 状态管理概览

页面每次被回传到服务器的时候都会创建 Web 页面类的一个新实例。在传统的 Web 开发中&#xff0c;这意味着在每次回传的过程中&#xff0c;页面中所有与页面和控件相关联的信息都将被丢失。例如&#xff0c;如果用户在一个文本框中输入了信息&#xff0c;那么在浏览器或者其他…

linux udp端口大数据包,Linux协议栈中UDP数据报从网卡到用户空间流程总结

NAPI驱动流程&#xff1a;中断发生-->确定中断原因是数据接收完毕(中断原因也可能是发送完毕&#xff0c;DMA完毕&#xff0c;甚至是中断通道上的其他设备中断)-->通过netif_rx_schedule将驱动自己的napi结构加入softnet_data的poll_list链表&#xff0c;禁用网卡中断&am…

浅谈.NET技术公司的实习生培养

浅谈.NET技术公司的实习生培养背景近几年.NET开发者市场的越发不景气&#xff0c;一毕业就选择.NET技术的开发者更是少之又少。一方面是公司效益的日益提高&#xff0c;一方面却是招聘优秀人才的速度总是赶不上公司发展的速度&#xff0c;这样的矛盾不断的倾轧着技术管理者的内…

禁止自动播放功能

运行gpedit.msc打开组策略&#xff0c;在“管理模板--系统”右侧双击“关闭自动播放”&#xff0c;然后设置为“已启用”&#xff0c;并在“关闭自动播放”下拉列表中选择“所有驱动器”&#xff0c;最后“确定”即可。这个设置在“计算机配置”和“用户配置”中都有&#xff0…

MBR的Linux分区机制启动过程,linux系统启动流程(MBR)

总&#xff1a;POST---> Boot Squence ---> Bootloader ---> kernel ---> init---> 完成启动系统&#xff1a;CentOS61、按下电源&#xff0c;cpu找到CMOS中的BIOS并运行起来&#xff0c;这个小程序会完成硬件自检。BIOS&#xff1a;Basic Input and Output Sys…

.netcore 极速接入第三方登录

新年新气象&#xff0c;趁着新年的喜庆&#xff0c;肝了十来天&#xff0c;终于发了第一版&#xff0c;希望大家喜欢。如果有不喜欢看文字的童鞋&#xff0c;可以直接看下面的地址体验一下&#xff1a;Github: https://github.com/mrhuo/MrHuo.OAuth唯一官网&#xff1a;https:…

linux watch 文件大小,Linux watch命令的使用

1.命令简介watch 命令以周期性的方式执行给定的命令&#xff0c;并全屏显示执行结果。watch 是一个非常实用的命令&#xff0c;基本所有的 Linux 发行版都带有。如同名字一样&#xff0c;watch 可以帮助监测一个命令的运行结果&#xff0c;省得我们一遍遍地手动运行。比如 tail…

在ISA 2006标准版上定制带宽和限制流量(测试)

最的忙于工作上的事&#xff0c;有点烦躁&#xff0c;很少有心情能静下来去看看书或是做些实验了。这是个不好的现象。 一直想着在ISA SERVER上做一些带宽和流量方面的测试&#xff0c;没有找到较好的软件。偶尔从朋友那得到一款&#xff0c;虽说是英文的&#xff0c;也蛮不错…

.NET 中 async 和 await

前言C# 中的 Async 和 Await 关键字是异步编程的核心。使用这两个关键字可以轻松创建异步方法。使用 async 关键字定义的异步方法简称“异步方法”。异步编程并发的一种形式&#xff0c;它采用furture模式或回调(callback)机制&#xff0c;以避免产生不必要的线程。.Net中futur…

Javascript 常用技巧 [2]

Javascript 常用技巧 [2] /**请问如何去掉主页右面的滚动条&#xff1f; <!-- <body scroll"no"> --> <!-- <body style"overflow-y:hidden"> --> ******************************** 怎样不使用页面的缓存&#xff1f;即每一次打…

mongodb可视化工具 linux,Linux中安装启动MongoDB与可视化工具

MongoDB 提供了 linux 各发行版本 64 位的安装包&#xff0c;你可以在官网下载安装包。下载地址&#xff1a;https://www.mongodb.com/download-center#community下载完安装包&#xff0c;并解压 tgz(以下演示的是 64 位 Linux上的安装) 。curl -O https://fastdl.mongodb.org/…

年轻有为的老黄2020

0x01 不知道开篇要说什么好&#xff0c;那就来个经典的 0x01 吧。这个世界不止苟且&#xff0c;还有诗和远方。工作 工作上面还算是比较忙碌的&#xff0c;在20年也做了很多东西&#xff0c;本来面试进公司的时候title是高开&#xff0c;在基础架构组&#xff0c;光杆部门。过完…

VS.NET调试问题

Q:VS.NET调试问题 A:关于VisualStudio.NET里调试出现的一系列问题&#xff0c;例如没有权限调试Web服务器&#xff0c;不属于Debugger Users组、无法调试等情况&#xff0c;都可以在The VS7 Debugger doesn’t work. What can I do(http://blogs.msdn.co…

linux调用odbc接口乱码,linux中pypyodbc读取GB编码mdb中文乱码解决办法

当前1.3.3版本的pypyodbc在linux系统上面已经可以读取有中文字符的mdb文件,不再出现异常,但是读取的中文字符却全是乱码。下面是根据一些现象的合理推论:mdb文件来自于windows系统,其中的中文字符使用GB编码无疑,但linux系统上mdbtools提供的odbc驱动底层已经执行了编码转换,将…

推荐:Dapper扩展-Dapper.SimpleCRUD

背景Dapper目前应该是大家比较喜欢的orm框架之一&#xff0c;但是它灵活的背后&#xff0c;还是有很多不尽人意的地方&#xff0c;谁想编写基本的读取/插入/更新/删除语句&#xff1f;下面推荐SimpleCRUD为Dapper提供了简单的CRUD帮助器。解放了大家&#xff0c;提高生产力。功…

创建虚拟磁盘的小工具软件plainmaker.exe

此小工具,在虚拟机中做集群实现时用到!其下载地址如下:[url]http://www.vmware.cn/Soft/69.html[/url]

Linux下的MySQL测试,Linux下MySQL命令(1)

启动命令&#xff1a;$ ./mysqld_safe --defaults-file/home/mysql/local/mysql_sale_mirror/etc/my.cnf --basedir/home/mysql/local/mysql_sale_mirror/ --datadir/home/mysql/local/mysql_sale_mirror/var/ --pid-file/home/mysql/local/mysql_sale_mirror/var/mysql.pid --…