猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

时间:2022-10-11 07:58:26

????作者简介:博主是一位.Net开发者,同时也是RPA和低代码平台的践行者。
????个人主页:会敲键盘的肘子
????系列专栏:SqlSugar ORM
????专栏简介:SqlSugar是一款来自未来的ORM,拥有超前的理念,需求领跑第一线,在设计理念上就算不更新几年都不会过时,是一款真正用了功能齐全的ORM框架。博主在工作中学习和实战SqlSugar,形成本专栏,希望可以帮助到您解决问题。
????座右铭:总有一天你所坚持的会反过来拥抱你。


猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

???? 前言

​ 随着华为、中兴事务,国产数据库市场相信是未来是趋势走向,纵观 .net core 整个圈子FreeSqlSqlSugar(排名不分先后)都已早早支持国产数据库,比如人大金仓、神通、达梦,针对不同的项目要求支持适配不同的国产数据库。今天我们使用 SqlSugar ORM 来体验人大金仓国产数据库

SqlSugar是一款来自未来的ORM开箱即用,拥有超前的理念,需求领跑第一线,在设计理念上就算不更新几年都不会过时,是一款真正用了功能齐全的ORM框架。

感谢果糖大数据科技团队对SqlSugar的维护和更新,北京人大金仓信息技术股份有限公司提供的支持。


????本文关键字:国产数据库、人大金仓、SqlSugar、ORM

???? 人大金仓

♈ 基本介绍

KingbaseES是一款面向事务处理应用,兼顾简单分析应用的企业级关系型数据库,产品融合了金仓在数据库领域多年的产品研发经验和企业级应用经验,可满足各行业用户多种场景的数据处理需求。

​ 金仓数据库管理系统 KingbaseES 支持多种操作系统和硬件平台: 支持 Linux、Windows、国产 Kylin 等数十个操 作系统产品版本,支持通用 x86_64 及国产龙芯、飞腾、申威等 CPU 硬件体系架构。Windows 平台的金仓数据库管 理系统 KingbaseES 提供标准版。

​ 金仓数据库管理系统 KingbaseES 软件能够提供一主一备以及一主多备的高可用集群架构,实现数据及实例级 (异地) 故障容灾,也能够提供多节点并行服务,内存融合及存储共享,实现高并发性能利用最大化,结合读写分离或备份使用同步实现数据保护最大化。

♉ 安装模式

​ 根据操作习惯的不同,您可以选择图形化安装控制台安装静默安装的方式安装部署金仓数据库管理系统 KingbaseES。推荐使用图形化安装

安装方式 简介
图形化安装 启用图形化界面进行向导式安装。
控制台安装 使用命令行方式进行向导式安装。
静默安装 通过编写配置文件,执行命令进行安装,安装过程不需要干预

♊ License 说明

​ 数据库 license 是金仓数据库管理系统 KingbaseES 提供的授权文件,其中会对数据库有效日期、发布类型、最大 并发连接数 mac 地址、ip 等信息进行设置。 如果在 license 文件中信息与安装环境中相关信息不匹配,数据库将无法启动。

♋ 安装前准备工作

⭐ 软硬件安装要求

​ Windows 版本的金仓数据库管理系统 KingbaseES V8.6 可以运行在通用 X86_64 体系结构的 CPU 上。其中标准版需要内存512MB 以上以及10GB 以上的硬盘空闲空间。

⭐ 检查安装文件是否正常

​ 本文使用通用型数据库标准版,下载链接:KingbaseES_V008R006C006B0021_Win64_install

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 您在获得安装程序(iso 文件)的同时,应该会获得一个 MD5 值或 SHA1 值。建议先通过以下命令查看安装程序文件对应的 MD5 值或 SHA1 值,再和拿到的 MD5 值或 SHA1 值进行比对。如果一致说明安装文件正常;如果不 一致说明安装文件可能不完整,安装过程可能无法正常完成。

​ 假设拿到的安装包文件是 KingbaseES_V008R006C006B0021_Win64_install.iso,

查看其 MD5 值: certutil -hashfile C:\KingbaseES_V008R006C006B0021_Win64_install.iso MD5

查看其 SHA1 值: certutil -hashfile C:\KingbaseES_V008R006C006B0021_Win64_install.iso SHA1

如下图所示,

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

⭐ 安装目录

​ 金仓数据库管理系统 KingbaseES 安装过程中有默认的安装目录 C:\Program Files\Kingbase\ES\V8

⭐ 数据目录

​ 数据目录是金仓数据库管理系统 KingbaseES 中存放数据文件的目录,默认是在安装目录下的 data 目录。也可以与安装目录分开单独设置。您也可以根据系统的业务数据量来设置数据目录路径。默认数据目录是安装目录下的 data 目录。如果使用默认安装目录,则数据目录默认为 C: \ProgramFiles\Kingbase\ES\V8\data

注意: 数据目录不必事先创建。安装过程中会提示指定数据目录,如果目录不存在安装程序会自动创建。

♌ 图形化安装

⭐ 启动安装程序

右键以管理员身份运行金仓数据库管理系统 KingbaseES V8.6 安装程序,将弹出安装程序窗口,如图所示。

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 选择语言(默认 < 简体中文 >),并点击“确定”按钮,继续安装。

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 点击【下一步】,继续本次安装。

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

⭐ 许可协议

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 默认“我接受许可协议条款”的选择框未选中,【下一步】按钮置灰。当且仅当选择“我接受许可协议条款”后,【下一步】按钮方有效。

​ 若点击【取消】按钮,将弹出取消安装提示窗口,点击【退出】按钮,退出安装程序。若点击【继续】,则回到安装界面,继续安装。

⭐ 选择安装集

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 根据安装后数据库服务功能的不同,金仓数据库管理系统 KingbaseES V8.6 可分为完全安装、客户端安装和定制安装三种安装集。

  • 完全安装:包括数据库服务器、接口、数据库开发管理工具、数据库迁移工具、数据库部署工具。选择“完全安装”安装集,系统将安装 KingbaseES 所有组件,点击【下一步】,至选择授权文件。

  • 客户端安装:包括接口、数据库开发管理工具、数据库迁移工具、数据库部署工具。选择“客户端安装”安装集,系统将安装 KingbaseES 的所有客户端工具和编程接口,点击【下一步】,至选择安装文件夹。

  • 定制安装:在数据库服务器、接口、数据库开发管理工具、数据库迁移工具、数据库部署工具所有组件中*选择。选择“定制安装”安装集,可根据需求选择安装所需功能部件,点击【下一步】,至选择产品功能组件。

    如选择定制安装的安装集,您通过点击功能组件项选择或去除对应的组件。如果要安装集群节点上的数据库服务,必须要安装“数据库部署工具”。点击【下一步】,继续安装。

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

⭐ 选择授权文件

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 您在本步骤需要选择授权文件,授权文件路径默认为空,点击【选择】按钮以选择本机上的授权文件。若指定的授权文件合法,则将显示授权文件的详细信息。进入该步骤【下一步】按钮默认置灰,若授权文件通过验证,则【下一步】按钮有效。

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

授权文件在下载安装包的页面下载,本文使用windows版本。

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

⭐ 选择安装文件夹

​ 此步骤用于选择安装路径。默认安装路径为: D:\Program Files\Kingbase\ES\V8

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 您点击【选择】按钮,弹出文件选择对话框,可选择其他安装路径。

​ 点击【恢复缺省文件夹】按钮,将安装路径恢复为默认安装路径。

​ 点击【下一步】按钮,继续安装。

⭐ 预安装摘要

​ 您在此步骤会看到即将安装产品的摘要信息,包括:

  • 产品名称。
  • 安装文件夹。
  • 指定安装的功能组件。
  • 安装路径所在磁盘空间信息。

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

⭐ 正在安装

​ 您点击【安装】按钮后,系统开始安装 KingbaseES,安装过程不断刷新安装进度。

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 如选择“完全安装”安装集,安装进度 100% 之后,将至 初始化数据库。

​ 如选择“客户端安装”安装集,安装进度 100% 之后,将至 安装完成。

​ 如选择“定制安装”安装集,并选择安装了数据库服务器组件,安装进度 100% 之后,将至 初始化数据库。

⭐ 初始化数据库

​ 首先选择数据库数据目录,默认数据目录为安装目录下的 data 目录。如使用默认安装目录,则数据目录默认为

D:\Program Files\Kingbase\ES\V8\data

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 点击【选择】按钮,弹出文件选择对话框,选择自定义数据目录。

​ 您点击【恢复缺省文件夹】按钮,将数据目录恢复为默认的数据目录。

​ 点击【下一步】按钮,继续设置如下初始化数据库参数:

  • 默认端口为:54321(可自定义)
  • 默认账户为:system(可自定义)
  • 密码(自定义)
  • 默认字符集编码为:GBK(可选 UTF8、GB18030)
  • 默认数据库兼容模式为:ORACLE(可选 PG)
  • 默认大小写敏感为:是(可选否)
  • 默认数据块大小为:8k(可选 16k、32k)

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

⭐ 安装完成

​ 若安装过程中没有出现任何警告或错误,将显示如下界面。单击【完成】退出安装程序。若安装过程中出现任何警告或错误,则窗口中显示日志文件位置,您可以打开日志文件查看具体错误信息。

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

♍ 命令行安装和静默安装

​ 关于命令行安装和静默安装,大家可以下载人大金仓官网的安装手册自行安装。

♎ 增删组件

⭐ 图形化增删组件

对于选择客户端安装集或定制安装集的数据库,后续可根据需要增加其他未安装的功能组件。

⭐ 启动

​ 运行安装程序 KingbaseES_V008R006C006B0021_Win64_install.exe,以管理员身份运行。选择“修改存在的实例”并选中安装目录,点击“确定”按钮。

⭐ 添加功能

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 选择【添加功能】选项,点击【下一步】。

​ 点击【取消】按钮,可以退出,若无特殊说明,以下各步骤皆与此相同。

⭐ 确认

​ 点击【下一步】按钮,继续安装;点击【取消】按钮,取消安装。

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

⭐ 选择功能组件

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 您可以选中需要添加的功能组件,置灰无法选择的组件是已经安装的组件。点击【下一步】按钮,继续安装。

⭐ 安装进度

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 此步骤用于显示安装进度。如果选择的组件包含数据库服务器,则后续会继续选择授权文件、初始化数据库步

骤。

⭐ 完成安装

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 若安装过程中没有出现任何警告或错误,将显示如下界面。单击【完成】退出安装程序

⭐ 删除组件

​ 关于删除组件,大家可以下载人大金仓官网的安装手册自行操作。

♏ 命令行增删组件

​ 关于命令行增删组件,大家可以下载人大金仓官网的安装手册自行安装。

???? 创建数据库和数据表

♈ 数据库开发和管理工具

​ 我们使用刚刚安装的数据库开发和管理工具来创建数据库和数据表。

♉ 新建连接

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 点击数据库 >> 新建连接。

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 选择默认数据库 >> 【下一步】。

​ 输入刚才安装时设置的密码后,点击左下角测试链接。

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 连接成功会出现下图弹窗。

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

♊ 创建数据表

​ 表空间 >> 【新建表空间】,创建数据表。

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

​ 这里我们简单创建3张表,分别是用户表sys_user、角色表sys_role、菜单功能表sys_feature、用户角色映射表sys_userrole、角色菜单映射表sys_rolefeature

⭐ sys_user

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

id作为主键

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

⭐ sys_role

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

id作为主键

⭐ sys_feature

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

id作为主键

⭐ sys_userrole

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

id作为主键

⭐ sys_rolefeature

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

这里ID之所以用36位字符,是软件里准备使用GUID,是微软对UUID标准的实现。

至于为什么是36位,原因如下:

这取决于您格式化Guid的方式:

  • Guid.NewGuid().ToString()=> 36个字符(带连字符的)
    输出:12345678-1234-1234-1234-123456789abc
  • Guid.NewGuid().ToString("D")=> 36个字符(连字符,与相同ToString()
    输出:12345678-1234-1234-1234-123456789abc
  • Guid.NewGuid().ToString("N")=> 32个字符(仅数字)
    输出:12345678123412341234123456789abc
  • Guid.NewGuid().ToString("B")=> 38个字符(大括号)
    输出:{12345678-1234-1234-1234-123456789abc}
  • Guid.NewGuid().ToString("P")=> 38个字符(括号)
    输出:(12345678-1234-1234-1234-123456789abc)
  • Guid.NewGuid().ToString("X")=> 68个字符(十六进制)
    输出:{0x12345678,0x1234,0x1234,{0x12,0x34,0x12,0x34,0x56,0x78,0x9a,0xbc}}

???? Sqlsugar

♈ 基本介绍

​ SqlSugar 是一款 老牌 .NET 开源ORM框架,由果糖大数据科技团队维护和更新 ,开箱即用最易上手的ORM框架 ,51Job和Boss直招简历数超过 国外框架 Nhibernate PetaPoco, 仅次于Dapper和EF Core , 占Dapper 40% 。

⭐ 功能介绍

  1. 相比EF Core【学习成本低一天学会】,多库支持更好 ,在国内拥有不逊色EF Core 的【开源生态】。
  2. 支持 .NET 百万级【大数据】写入和更新、分表和几十亿查询和统计等 拥有成熟方案。
  3. 支持 完整的SAAS一套应用 跨库查询 、租户分库 、租户分表 和 租户数据隔离。
  4. 支持【低代码】+工作流 (无实体多库兼容CRUD & JSON TO SQL )。
  5. 语法最爽的ORM、优美的表达式、仓储、UnitOfWork、DbContext、AOP。
  6. 支持 DbFirst、CodeFirst和【WebFirst】 3种模式开发。
  7. 简单易用、功能齐全、高性能、轻量级、服务齐全、官网教程文档、有专业技术支持一天18小时服务。

⭐ 数据库支持

关系型数据库 MySql、SqlServer、Sqlite、Oracle 、 postgresql、达梦、人大金仓、神通数据库、瀚高、Access 、MySqlConnector、华为 GaussDB 、南大通用 GBase 、Odbc、自定义
时序数据库 QuestDb (适合几十亿数据分析,模糊查询,自动分表存储 ,缺点不支持删除)
列式存储库 Clickhouse(适用于商业智能领域(BI),缺点大小写必须和库一样,不支持事务)
即将上线 Mongodb(mongodb.entities)TDengine、Sybase…

♉ Nuget安装

⭐ 打开Nuget

​ 点击项目引用 >> 右键 Nuget管理

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

⭐ 安装SqlSugar

​ .Net Core 3 & 5 & 6 &7

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

⭐ SqlSugar源码

​ 博主这里因为需要对SqlSugar做一些修改,所以用了源码,结构如下,

猿创征文|【国产数据库实战】一文学会应用SqlSugar访问及操作人大金仓数据库

♊ 人大金仓 .NET 操作数据库

⭐ 人大金仓枚举

分为R6和R3一定要看 下面的安装 小有区别

public enum DbType
{
    MySql ,
    SqlServer,
    Sqlite,
    Oracle,
    PostgreSQL,
    Dm, 
    Kdbndp // 人大金仓 只支持.NET CORE
}

⭐ 安装

R3
版本只需要引用 SqlSugarCore

R6
版本需要单独安装 SqlSugarCore.Kdbndp 6.1 和 SqlSugarCore

⭐ 人大金仓优点

基本上和PgSql一模一样更贴近开发功能也继承了pgsql所有功能,对开发人员比较友好

⭐ 连接字符串

appsettings.json配置

"ConnectionStrings": {
    "kdbndp": "data source=127.0.0.1;database=test;Port=54321;UID=SYSTEM;PWD=system", //测试版本用人大金仓数据库
  },

UnitOfWork.cs 工作单元实现

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using SqlSugar;
using System;

namespace Sys.Infrastructure.Data
{
    /// <summary>
    /// 工作单元实现
    /// </summary>
    public abstract class UnitOfWork : IUnitOfWork
    {
        public UnitOfWork(IConfiguration configuration, IHttpContextAccessor accessor)
        {
            Configuration = configuration;
            HttpContextAccessor = accessor;
        }

        protected IConfiguration Configuration { get; set; }
        public IHttpContextAccessor HttpContextAccessor { get; set; }
        protected DateTime StartTime { get; set; }
        protected DateTime EndTime { get; set; }

        public SqlSugarClient Db { get; protected set; }

        public void BeginTran() => Db.BeginTran();

        public void CommitTran()
        {
            try
            {
                Db.CommitTran();
            }
            catch (Exception ex)
            {
                Db.RollbackTran();
                throw ex;
            }
        }

        public void RollbackTran() => Db.RollbackTran();
    }
}

KdbndpOfWork.cs

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Serilog;
using SqlSugar;
using Supcon.APS.Common;
using Supcon.APS.Domain.Core;
using Supcon.APS.Domain.Entities;
using Supcon.APS.Domain.Entities.Sys;
using Supcon.APS.Domain.IRepository;
using System;
using System.IO;
using System.Linq;


namespace Sys.Infrastructure.Data
{
    public class KdbndpOfWork : UnitOfWork, IUnitOfWork
    {
        public KdbndpOfWork(IConfiguration configuration, IHttpContextAccessor accessor) : base(configuration, accessor)
        {
            Db = new SqlSugarClient(new ConnectionConfig
            {
                ConnectionString = configuration.GetConnectionString("kdbndpdb"), //数据库连接在 appsettings.json 中配置
                DbType = DbType.Kdbndp,
                IsAutoCloseConnection = true,
                IsShardSameThread = true,
                AopEvents = new AopEvents
                {
                    OnLogExecuted = OnLogExecuted,
                    OnLogExecuting = OnLogExecuting,
                    OnError = OnError
                }
            });
        }

        /// <summary>
        /// 当数据库操作执行出错时
        /// </summary>
        /// <param name="exception"></param>
        private static void OnError(SqlSugarException exception)
        {

        }

        /// <summary>
        /// 当数据库操作执行时
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        private static void OnLogExecuting(string sql, SugarParameter[] parameters)
        {
            //StartTime = DateTime.Now;
        }

        /// <summary>
        /// 当数据库操作执行完毕后
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        private static void OnLogExecuted(string sql, SugarParameter[] parameters)
        {
           // EndTime = DateTime.Now;
            
            //CreateHttpSqlLog(sql, parameters);
        }

       
    }
}

⭐ 仓储操作人大金仓数据库

仓储(包含查询、多表查询、插入、更新、删除等方法)

public interface IRepository<TEntity> : IRepository<Guid, TEntity, IUnitOfWork>
            where TEntity : ApsEntity, new()
    {

    }

    public interface ISupplyChanRepository<TEntity> : IRepository<int, TEntity, IUnitOfWork>
        where TEntity : SupplyChanEntity, new()
    {

    }

    public interface IRepository<TKey, TEntity, TUnitOfWork>
        where TEntity : Entity<TKey>, new()
        where TUnitOfWork : IUnitOfWork
    {
        #region 查询

        /// <summary>
        /// 是否存在满足指定条件的数据
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <returns></returns>
        bool IsExist(Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>
        /// 统计数据条数
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <returns></returns>
        int Count(Expression<Func<TEntity, bool>> whereExpression = null);

        /// <summary>
        /// 获取一条数据
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <returns></returns>
        Task<TEntity> SingleAsync(Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>
        /// 查询
        /// </summary>
        /// <returns></returns>
        Task<List<TEntity>> QueryAsync();

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="strWhere">查询字符串</param>
        /// <returns></returns>
        Task<List<TEntity>> QueryAsync(string strWhere);

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <returns></returns>
        Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression);

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="strWhere">查询字符串</param>
        /// <param name="strOrderByFileds">排序字段,如:Name Asc, Age Desc</param>
        /// <returns></returns>
        Task<List<TEntity>> QueryAsync(string strWhere, string strOrderByFileds);

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <param name="strOrderByFileds">排序字段,如:Name Asc, Age Desc</param>
        /// <returns></returns>
        Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression, string strOrderByFileds);

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <param name="orderByExpression">排序表达式</param>
        /// <param name="isAsc">是否为升序</param>
        /// <returns></returns>
        Task<List<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true);

        /// <summary>
        /// 查询前 N 条数据
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <param name="count">记录数</param>
        /// <param name="strOrderByFileds">排序字段,如:Name Asc, Age Desc</param>
        /// <returns></returns>
        Task<List<TEntity>> TopAsync(
            Expression<Func<TEntity, bool>> whereExpression,
            int count,
            string strOrderByFileds);

        /// <summary>
        /// 查询前 N 条数据
        /// </summary>
        /// <param name="strWhere">条件字符串</param>
        /// <param name="count">记录数</param>
        /// <param name="strOrderByFileds">排序字段,如:Name Asc, Age Desc</param>
        /// <returns></returns>
        Task<List<TEntity>> TopAsync(
            string strWhere,
            int count,
            string strOrderByFileds);

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="strWhere">条件字符串</param>
        /// <param name="pageIndex">当前页数</param>
        /// <param name="pageSize">分页大小</param>
        /// <param name="strOrderByFileds">排序字段,如:Name Asc, Age Desc</param>
        /// <param name="totalCount">总记录数</param>
        /// <returns></returns>
        List<TEntity> Pages(string strWhere, int pageIndex, int pageSize, string strOrderByFileds, out int totalCount);

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <param name="pageIndex">当前页数</param>
        /// <param name="pageSize">分页大小</param>
        /// <param name="orderByExpression">排序表达式</param>
        /// <param name="isAsc">是否为升序</param>
        /// <param name="totalCount">总记录数</param>
        /// <returns></returns>
        List<TEntity> Pages(Expression<Func<TEntity, bool>> whereExpression,
            int pageIndex, int pageSize, Expression<Func<TEntity, object>> orderByExpression, bool isAsc,
            out int totalCount);

        /// <summary> 
        /// 多表查询
        /// </summary> 
        /// <typeparam name="T1">实体1</typeparam> 
        /// <typeparam name="T2">实体2</typeparam> 
        /// <typeparam name="TResult">返回类型</typeparam>
        /// <param name="joinExpression">关联表达式 (join1, join2) => new object[] { JoinType.Left, join1.UserNo == join2.UserNo }</param> 
        /// <param name="selectExpression">返回表达式 (s1, s2) => new { Id =s1.UserNo, Id1 = s2.UserNo }</param>
        /// <param name="whereLambda">查询表达式 (w1, w2) => w1.UserNo == "")</param> 
        /// <returns></returns>
        Task<List<TResult>> QueryMuchAsync<T1, T2, TResult>(
            Expression<Func<T1, T2, object[]>> joinExpression,
            Expression<Func<T1, T2, TResult>> selectExpression,
            Expression<Func<T1, T2, bool>> whereLambda = null) where T1 : class, new();

        /// <summary> 
        ///多表查询
        /// </summary>
        Task<List<TResult>> QueryMuchAsync<T1, T2, T3, TResult>(
            Expression<Func<T1, T2, T3, object[]>> joinExpression,
            Expression<Func<T1, T2, T3, TResult>> selectExpression,
            Expression<Func<T1, T2, T3, bool>> whereLambda = null) where T1 : class, new();

        /// <summary> 
        ///多表查询
        /// </summary>
        Task<List<TResult>> QueryMuchAsync<T1, T2, T3, T4, TResult>(
            Expression<Func<T1, T2, T3, T4, object[]>> joinExpression,
            Expression<Func<T1, T2, T3, T4, TResult>> selectExpression,
            Expression<Func<T1, T2, T3, T4, bool>> whereLambda = null) where T1 : class, new();

        Task<List<TResult>> QueryMuchAsync<T1, T2, T3, T4, T5, TResult>(
            Expression<Func<T1, T2, T3, T4, T5, object[]>> joinExpression,
            Expression<Func<T1, T2, T3, T4, T5, TResult>> selectExpression,
            Expression<Func<T1, T2, T3, T4, T5, bool>> whereLambda = null) where T1 : class, new();

        Task<List<TResult>> QueryMuchAsync<T1, T2, T3, T4, T5, T6, TResult>(
            Expression<Func<T1, T2, T3, T4, T5, T6, object[]>> joinExpression,
            Expression<Func<T1, T2, T3, T4, T5, T6, TResult>> selectExpression,
            Expression<Func<T1, T2, T3, T4, T5, T6, bool>> whereLambda = null) where T1 : class, new();

        #endregion

        #region 新增

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entities">实体(集合)</param>
        /// <returns></returns>
        Task<List<TEntity>> AddAsync(params TEntity[] entities);

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="insertColumns">指定要插入的列</param>
        /// <returns></returns>
        Task<TEntity> AddAsync(TEntity entity, Expression<Func<TEntity, object>> insertColumns);

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entities">实体集合</param>
        /// <param name="insertColumns">指定要插入的列</param>
        /// <returns></returns>
        Task<List<TEntity>> AddAsync(TEntity[] entities, Expression<Func<TEntity, object>> insertColumns);

        #endregion

        #region 更新

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="updateColumns">指定要更新的列</param>
        /// <param name="ignoreColumns">指定要忽略的列</param>
        /// <returns></returns>
        Task<bool> UpdateAsync(TEntity entity,
            Expression<Func<TEntity, object>> updateColumns = null,
            Expression<Func<TEntity, object>> ignoreColumns = null);

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entities">实体集合</param>
        /// <param name="updateColumns">指定要更新的列</param>
        /// <param name="ignoreColumns">指定要忽略的列</param>
        /// <returns></returns>
        Task<bool> UpdateAsync(TEntity[] entities,
            Expression<Func<TEntity, object>> updateColumns = null,
            Expression<Func<TEntity, object>> ignoreColumns = null);

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="whereExpression">条件表达式</param>
        /// <param name="anonymous">要更新的值(匿名对象)</param>
        /// <returns></returns>
        Task<int> UpdateAsync(Expression<Func<TEntity, bool>> whereExpression, dynamic anonymous);

        #endregion

        #region 删除

        /// <summary>
        /// 删除(Support IPhantomEntity)
        /// </summary>
        /// <param name="entities">实体(集合)</param>
        /// <returns></returns>
        Task<int> DeleteAsync(params TEntity[] entities);

        /// <summary>
        /// 删除(Support IPhantomEntity)
        /// </summary>
        /// <param name="ids">主键(集合)</param>
        /// <returns></returns>
        Task<int> DeleteAsync(params TKey[] ids);

        / <summary>
        / 删除(Support IPhantomEntity)
        / </summary>
        / <param name="whereExpression">条件表达式</param>
        / <returns></returns>
        //Task<int> DeleteAsync(Expression<Func<TEntity, bool>> whereExpression);

        / <summary>
        / 删除(Support IPhantomEntity)
        / </summary>
        / <param name="strWhere">条件字符串</param>
        / <returns></returns>
        //Task<int> DeleteAsync(string strWhere);

        #endregion

        #region 更新或新增

        /// <summary>
        /// 更新或插入
        /// http://www.codeisbug.com/Doc/8/1172
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="upsertColumns">指定要更新或插入的列</param>
        /// <param name="ignoreColumns">指定要忽略的列</param>
        /// <returns></returns>
        TEntity UpsertAsync(TEntity entity,
            Expression<Func<TEntity, object>> upsertColumns = null,
            Expression<Func<TEntity, object>> ignoreColumns = null);

        /// <summary>
        /// 更新或插入
        /// http://www.codeisbug.com/Doc/8/1172
        /// </summary>
        /// <param name="entities">实体集合</param>
        /// <param name="upsertColumns">指定要更新或插入的列</param>
        /// <param name="ignoreColumns">指定要忽略的列</param>
        /// <returns></returns>
        Task<List<TEntity>> UpsertAsync(List<TEntity> entities,
            Expression<Func<TEntity, object>> upsertColumns = null,
            Expression<Func<TEntity, object>> ignoreColumns = null);

        /// <summary>
        /// 更新或插入
        /// </summary>
        /// <param name="entity">实体</param>
        /// <param name="insertColumns">指定要插入的列</param>
        /// <param name="ignoreInsertColumns">指定要忽略的插入列</param>
        /// <param name="updateColumns">指定要更新的列</param>
        /// <param name="ignoreUpdateColumns">指定要忽略的更新列</param>
        /// <returns></returns>
        TEntity UpsertAsync(TEntity entity,
            Expression<Func<TEntity, object>> insertColumns = null,
            Expression<Func<TEntity, object>> ignoreInsertColumns = null,
            Expression<Func<TEntity, object>> updateColumns = null,
            Expression<Func<TEntity, object>> ignoreUpdateColumns = null);

        /// <summary>
        /// 更新或插入
        /// </summary>
        /// <param name="entities">实体集合</param>
        /// <param name="insertColumns">指定要插入的列</param>
        /// <param name="ignoreInsertColumns">指定要忽略的插入列</param>
        /// <param name="updateColumns">指定要更新的列</param>
        /// <param name="ignoreUpdateColumns">指定要忽略的更新列</param>
        /// <returns></returns>
        Task<List<TEntity>> UpsertAsync(List<TEntity> entities,
            Expression<Func<TEntity, object>> insertColumns = null,
            Expression<Func<TEntity, object>> ignoreInsertColumns = null,
            Expression<Func<TEntity, object>> updateColumns = null,
            Expression<Func<TEntity, object>> ignoreUpdateColumns = null);

        #endregion
    }

通用实体

public abstract class Entity<TKey>
    {
        [SugarColumn(IsPrimaryKey = true)]
        public virtual TKey Id { get; set; }
    }

    public abstract class KdbndpEntity : Entity<Guid>, IPhantomEntity
    {
        public KdbndpEntity()
        {
            Id = GuidGenerator.Current.Create();
        }

        /// <summary>
        /// 创建时间
        /// </summary>
        [SugarColumn(ColumnName = "create_time", IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
        public virtual DateTime CreateTime { get; set; } = DateTime.Now;

        /// <summary>
        /// 更新时间
        /// </summary>
        [SugarColumn(ColumnName = "update_time", IsNullable = true, IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
        public virtual DateTime? UpdateTime { get; set; }

        [SugarColumn(ColumnName = SqlSugarConst.PhantomColumnName)]
        public bool IsDeleted { get; set; }
        public virtual string GetMainKey()
        {
            return this.Id.ToString();
        }
    }

用户表实体

/// <summary>
    /// 用户表
    /// </summary>
    [SugarTable("sys_user")]
    public class User : KdbndpEntity
    {
        /// <summary>
        /// 用户名
        /// </summary>
        public string Username { get; set; }
        /// <summary>
        /// 昵称
        /// </summary>
        public string Nickname { get; set; }
        /// <summary>
        /// 手机
        /// </summary>
        public string Phone { get; set; }
        /// <summary>
        /// 邮箱
        /// </summary>
        public string Email { get; set; }
        /// <summary>
        /// 密码
        /// </summary>
        public string Password { get; set; }

    }

用户表仓储接口

	/// <summary>
    /// 用户表仓储接口
    /// </summary>
    public interface IUserRepository : IRepository<User>
    {
    }

用户表仓储

public class UserRepository : Repository<User>, IUserRepository
    {
        public UserRepository(KdbndpOfWork unitOfWork) : base(unitOfWork)
        {

        }
    }

多表查询

public List<UserModel> Query(UserQuery query)
        {
            return Db.Queryable<User, UserRole>((p, userRole) => p.RoleId == userRole.Id)
                     .WhereIF(!IsNullOrEmpty(query.Username), p => p.Username.Contains(query.Username, StringComparison.OrdinalIgnoreCase))
                     .WhereIF(!IsNullOrEmpty(query.Nickname), p => p.Nickname == query.Nickname)
                     .WhereIF(!IsNullOrEmpty(query.RoleName), (p, userRole) => userRole.Id.Contains(query.Id, StringComparison.OrdinalIgnoreCase))
                     .Select((p, unitType) =>
                     
                         new UserModel()
                         {
                             Username = p.Username,
                             Nickname = p.Nickname,
                             CreateTime = p.CreateTime,
                             Phone = p.Phone,
                             Password = p.Password,
                             Id = p.Id,
                             RoleId = userRole.Id.ToString(),
                             UpdateTime = p.UpdateTime,
                             Email=p.Email
                         }
                     ).ToList();
                     
        }

插入

//返回插入行数
db.Insertable(insertObj).ExecuteCommand(); //都是参数化实现 //插入返回自增列db.Insertable(insertObj).ExecuteReturnIdentity(); //返回雪花ID 看文档3.1具体用法(在最底部)
long id= db.Insertable(实体).ExecuteReturnSnowflakeId();

???? 结语

​ 本文主要介绍了SqlSugar访问人大金仓数据库的实战,当然这仅仅只是SqlSugar的基本用法。下一篇文章,我们将介绍通过SqlSugar的工作单元模式进行多数据库访问,包括多类型MySQL、人大金仓、达梦等数据,或者同一种数据库的多个库。


文章中出现的任何错误请大家批评指出,一定及时修改。

希望写在这里的小伙伴能给个三连支持