一般一个业务系统里,单据都会有一个可读的单据号,比如单据日期(yyyyMMdd)+6位累加数字。可以系统内唯一,也可以模块内唯一。如果是SAAS系统,每个客户之间还要独立,比如A客户商品模块有流水号20220101000001,B客户商品模块也有20220101000001流水号。
这篇文章主要是说明用Expression,Func参数,实现统一的单据号生成代码。所以不考虑高并发,分布式的情况。如果是高并发,分布式应该用缓存,预生成,单独部署服务去生成。
生成单据号,需要知道当前是哪个模块,当前模块当前客户最近一条单据号,在上面累加。这里直接从数据库读最近一条记录。
需要解决的问题
一,系统内所有模块都可以用
因为是从数据库读,公司用efcore。外部传入模块Entity,ef就知道查哪个表了。总之这里从外部传入能唯一标识哪个模块就行。
先创建一个表Blog,字段number,type,date.注意连接字符串(MyContext.cs里)我用了绝对路径,因为生成数据库时,当前目录是项目路径。运行起来后就是当前路径是bin路径。这个你改一下你自己的绝对路径就行。数据库都是自动生成的。
ef 迁移不熟的看这个官方说明,要做的就是
1,代码写好
2 创建名为 InitialCreate 的迁移 dotnet ef migrations add InitialCreate
3创建数据库和架构 dotnet ef database update
流水号的逻辑,直接看代码吧,看懂你就会了,其实没啥东西。
二,可以指定生成条件,比如入库,出库都记录到库存流转模块, 但入库和出库需要可以通过流水号辨别。
源码里把type字段理解成出库入库标识就行了,当条件传入就行了。
三,可以指定生成规则
把生成规则也当参数传入就行了,见TNumberCreater
四,可以一次性生成多个。
这个没啥可说的,生成一个和生成N个的问题。注意哈,正常来说,生成N个流水号,那么这些流水号就被占用了,再请求流水号应该继续累计。但是我这里只是说用Expression,Func去解决公共生成流水号,不考虑并发,生成流水号也没有单独的服务。