基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理
我们在设计数据库表的时候,往往为了方便,主键ID一般采用字符串类型或者GUID类型,这样对于数据库表记录的迁移非常方便,而且有时候可以在处理关联记录的时候,提前对应的ID值。但有时候进行数据记录插入的时候,往往忽略了对ID的赋值处理。为了便于使用或者允许自动赋值,我们可以在数据访问基类中对GUID主键进行自动赋值处理。
1、实体类主键属性的处理
在我们设计基于SqlSugar的框架的时候,实体类定义一个基类Entity<T>,如下代码所示。
[Serializable]
public abstract class Entity<TPrimaryKey> : IEntity<TPrimaryKey>
{
/// <summary>
/// 实体类唯一主键
/// </summary>
[SqlSugar.SugarColumn(IsPrimaryKey = true, ColumnDescription = "主键")]
public virtual TPrimaryKey Id { get; set; }
一般可以扩展字符串,整形等等类型的实体类。
默认的Entity定义为整形的,如下所示。自增长的整形主键,不需要插入值,它在记录写入的时候获得对应的Id值。
[Serializable]
public abstract class Entity : Entity<int>, IEntity
{
/// <summary>
/// ID 主键,自增长类型
/// </summary>
[SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public override int Id { get; set; }
}
对于字符型类型的ID键,可以在构造函数中对ID进行初始化。
/// <summary>
/// 客户信息
/// 继承自Entity,拥有Id主键属性
/// </summary>
[SugarTable("T_Customer")]
public class CustomerInfo : Entity<string>
{
/// <summary>
/// 默认构造函数(需要初始化属性的在此处理)
/// </summary>
public CustomerInfo()
{
this.Id = System.Guid.NewGuid().ToString();
this.CreateTime = System.DateTime.Now; }
或者我们在数据插入一条新记录的时候,判断主键是否为空,然后赋值给它,或者唯一的GUID值。
使用Guid.NewGuid() 的处理,这样好处就是可以获得一个唯一的GUID值,而弊端是ID是无序的,没有先后顺序,对ID排序就是无意义了。
为了解决这个问题,我们还是引入Abp VNext的规则,生成一个有序的GUID值,同时在数据库访问基类,对插入记录、更新记录的时候,判断ID(对GUID类型或者字符串类型的主键ID)是否为空,为空则赋值一个有序的GUID给它,则可以完美解决问题了。
这样我们定义实体类的时候,ID值可以不初始化,让它保留位空,可以让用户主动设置值或者自动基类处理赋值。
/// <summary>
/// 客户信息
/// 继承自Entity,拥有Id主键属性
/// </summary>
[SugarTable("T_Customer")]
public class CustomerInfo : Entity<string>
{
/// <summary>
/// 默认构造函数(需要初始化属性的在此处理)
/// </summary>
public CustomerInfo()
{
this.CreateTime = System.DateTime.Now;
}
2、基类判断ID是否为空并赋值
对于GUID或者字符串类型的ID值,为什么设置有序GUID,可以参考链接了解下:https://github.com/abpframework/abp/blob/48c52625f4c4df007f04d5ac6368b07411aa7521/docs/zh-Hans/Guid-Generation.md
一般情况下,我们利用SqlSugar插入一个新记录的时候,是如下代码
/// <summary>
/// 创建对象
/// </summary>
/// <param name="input">实体对象</param>
/// <returns></returns>
public virtual async Task<bool> InsertAsync(TEntity input)
{
return await EntityDb.InsertAsync(input);
}
而为了判断Id是否为空,我们需要对ID类型进行判断,判断是否字符串类型或者GUID类型,如果为空则自动赋值它,因此我们在插入前进行一个判断处理,如下代码所示。
/// <summary>
/// 创建对象
/// </summary>
/// <param name="input">实体对象</param>
/// <returns></returns>
public virtual async Task<bool> InsertAsync(TEntity input)
{
SetIdForGuids(input);//如果Id为空,设置有序的GUID值
return await EntityDb.InsertAsync(input);
}
其中SetIdForGuids是获得有序GUID的值的函数。
/// <summary>
/// 为新创建的实体对象,设置主键Id的值为有序的GUID值(GUID类型或者字符串类型试用)
/// </summary>
public virtual void SetIdForGuids(TEntity entity)
{
if (entity is IEntity<Guid> entityWithGuidId && entityWithGuidId.Id == Guid.Empty)
{
//默认的GUID类型
var guidType = SequentialGuidType.SequentialAsString; switch(this.dbContext.DbType) //根据不同的数据库类型获取合适的生成序列方式
{
case SqlSugar.DbType.SqlServer:
guidType = SequentialGuidType.SequentialAtEnd;
break;
case SqlSugar.DbType.MySql:
case SqlSugar.DbType.PostgreSQL:
guidType = SequentialGuidType.SequentialAsString;
break;
case SqlSugar.DbType.Oracle:
guidType = SequentialGuidType.SequentialAsBinary;
break;
} var guid = GetSequentialGuid(guidType);
entityWithGuidId.Id = guid;
}
else if (entity is IEntity<string> entityWithStringId && string.IsNullOrWhiteSpace(entityWithStringId.Id))
{
var guid = GetSequentialGuid(SequentialGuidType.SequentialAsString);
entityWithStringId.Id = guid.ToString();
}
}
根据不同的数据库特性类型,构建不同的GUID值,如果是字符串的Id,我们统一采用 SequentialAsString 这个方式,这个也是支持字符串的常规排序处理,这样我们既获得了一个不重复的GUID值,也可以对ID进行排序,它是根据先后顺序排序的。
/// <summary>
/// 获取可以生成连续的GUID
/// </summary>
/// <returns></returns>
protected Guid GetSequentialGuid(SequentialGuidType sequentialGuidType)
{//使用指定序列创建的(生成连续的GUID)
//参考链接了解细节:(https://github.com/abpframework/abp/blob/48c52625f4c4df007f04d5ac6368b07411aa7521/docs/zh-Hans/Guid-Generation.md)
var options = new AbpSequentialGuidGeneratorOptions()
{
DefaultSequentialGuidType = sequentialGuidType
//SequentialAtEnd(default) 用于SQL Server.
//SequentialAsString 用于MySQL和PostgreSQL.
//SequentialAsBinary 用于Oracle.
};
return new SequentialGuidGenerator(options).Create();
}
添加几个字典类型(字符串ID)的记录进行测试。

可以看到ID的类型前缀部分是一样的,后面变化,以ID正序排序,是根据写入时间顺序处理的。

系列文章:
《基于SqlSugar的开发框架的循序渐进介绍(1)--框架基础类的设计和使用》
《基于SqlSugar的开发框架循序渐进介绍(2)-- 基于中间表的查询处理》
《基于SqlSugar的开发框架循序渐进介绍(3)-- 实现代码生成工具Database2Sharp的整合开发》
《基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理》
基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理的更多相关文章
- 基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口
在基于SqlSugar的开发框架中,我们设计了一些系统服务层的基类,在基类中会有很多涉及到相关的数据处理操作的,如果需要跟踪具体是那个用户进行操作的,那么就需要获得当前用户的身份信息,包括在Web A ...
- 基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录
在我们对数据进行重要修改调整的时候,往往需要跟踪记录好用户操作日志.一般来说,如对重要表记录的插入.修改.删除都需要记录下来,由于用户操作日志会带来一定的额外消耗,因此我们通过配置的方式来决定记录那些 ...
- 基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转
在前面随笔,我们介绍过这个基于SqlSugar的开发框架,我们区分Interface.Modal.Service三个目录来放置不同的内容,其中Modal是SqlSugar的映射实体,Interface ...
- 基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理
在早期的随笔就介绍过,把常规页面的内容拆分为几个不同的组件,如普通的页面,包括列表查询.详细资料查看.新增资料.编辑资料.导入资料等页面场景,这些内容相对比较独立,而有一定的代码量,本篇随笔介绍基于V ...
- 基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用
在我们实际项目开发过程中,往往需要根据实际情况,对组件进行封装,以更简便的在界面代码中使用,在实际的前端应用中,适当的组件封装,可以减少很多重复的界面代码,并且能够非常简便的使用,本篇随笔介绍基于El ...
- 基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用
刚完成一些前端项目的开发,腾出精力来总结一些前端开发的技术点,以及继续完善基于SqlSugar的开发框架循序渐进介绍的系列文章,本篇随笔主要介绍一下基于Vue3+TypeScript的全局对象的注入和 ...
- 基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理
在一个应用系统的开发框架中,往往很多地方需要用到缓存的处理,有些地方是为了便于记录用户的数据,有些地方是为了提高系统的响应速度,如有时候我们在发送一个短信验证码的时候,可以在缓存中设置几分钟的过期时间 ...
- 基于SqlSugar的开发框架循序渐进介绍(20)-- 在基于UniApp+Vue的移动端实现多条件查询的处理
在做一些常规应用的时候,我们往往需要确定条件的内容,以便在后台进行区分的进行精确查询,在移动端,由于受限于屏幕界面的情况,一般会对多个指定的条件进行模糊的搜索,而这个搜索的处理,也是和前者强类型的条件 ...
- 基于SqlSugar的开发框架循序渐进介绍(21)-- 在工作流列表页面中增加一些转义信息的输出,在后端进行内容转换
有时候,为了给前端页面输出内容,有时候我们需要准备和数据库不一样的实体信息,因为数据库可能记录的是一些引用的ID或者特殊字符,那么我们为了避免前端单独的进行转义处理,我们可以在后端进行统一的格式化后再 ...
随机推荐
- java中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思?重写跟重载的区别?
java中的方法重载发生在同一个类里面两个或者多个方法的方法名相同但是参数不同的情况.与此相对,方法覆盖是说子类重新定义了父类的方法.方法覆盖必须有相同的方法名,参数列表和返回类型. 覆盖者可能不会限 ...
- 『忘了再学』Shell基础 — 7、Bash基本功能(多命令顺序执行)
目录 1.多命令执行符: 2.多命令执行符&& 3.多命令执行符|| 4.&&和||联合应用 Linux系统支持多条命令顺序执行,就是我可以依次输入多条命令后,统一按E ...
- vulnhub mrRobot渗透笔记
mrRobot渗透笔记 靶机下载地址:https://www.vulnhub.com/entry/mr-robot-1,151/ kali ip 信息收集 首先依旧时使用nmap扫描靶机的ip地址 n ...
- AD18布线技巧
3. 快乐打孔模式(颜色配置)PCB 设计完成后,补回流孔,需要打开多层,软件设置如下: 设置方法: 转载原文链接未知
- 编写大型项目web页面 从写web登陆页面开始
web页面搭建需要准备什么工具 首先我们会和设计师沟通 我们需要一些检验设计的工具 ps 自动裁图 自动测量工具 (我这里安利一下一个工具 我用的cutterman) sketch 可以使用阿里的工具 ...
- 使用 Vuex + Vue.js 构建单页应用【新篇】
使用 Vuex + Vue.js 构建单页应用[新篇] 在去年的七月六号的时候,发布了一篇 使用 Vuex + Vue.js 构建单页应用 的文章,文章主要是介绍 vuex 的基本使用方法,发现对大部 ...
- properties和XML配置文件内容的获取
@ 目录 总结内容 1. Java中为什么要使用配置文件 2. Java中常用的配置文件类型有哪些以及它们的特点 Properties配置文件 XML配置文件 总结 总结内容 1. Java中为什么要 ...
- Uncaught TypeError: document.getElementsById is not a function
今天博主终于开始攻关javascript(俗称js)了,不过要注意了,它和java可是一丁点关系都没有,就像老婆饼和老婆一样. 下面就让我们来讨论一下博主这次犯下的低级错误吧 一.背景(解决方法在文末 ...
- 微信小程序,制作属于自己的Icon图标
前言 最近在接手一个微信小程序,发现里面的图标都是使用的image组件,看起来非常别扭,加载也不太顺畅. 就想着看看微信有没有类似自带的图标库可以使用. 有是有,就是太少了,翻来翻去好像也就 8 种, ...
- Java学习day27
今天跟着做了一个模拟龟兔赛跑的程序 只有一条赛道,乌龟和兔子在同一条赛道上比赛,使用了多线程 为了实现兔子睡觉,在run方法内增加了当前奔跑者是否是兔子的判断且当前奔跑步数是否是10的整数倍的判断,如 ...