作者简介:博主是一位.Net开发者,同时也是RPA和低代码平台的践行者。
个人主页:会敲键盘的肘子
系列专栏:SqlSugar ORM
专栏简介:SqlSugar是一款来自未来的ORM,拥有超前的理念,需求领跑第一线,在设计理念上就算不更新几年都不会过时,是一款真正用了功能齐全的ORM框架。博主在工作中学习和实战SqlSugar,形成本专栏,希望可以帮助到您解决问题。
座右铭:总有一天你所坚持的会反过来拥抱你。
随着华为、中兴事务,国产数据库市场相信是未来是趋势走向,纵观 .net core 整个圈子FreeSql和SqlSugar(排名不分先后)都已早早支持国产数据库,比如人大金仓、神通、达梦,针对不同的项目要求支持适配不同的国产数据库。今天我们使用 SqlSugar ORM 的工作单元模式来连接多个国产数据库。
SqlSugar是一款来自未来的ORM,开箱即用,拥有超前的理念,需求领跑第一线,在设计理念上就算不更新几年都不会过时,是一款真正用了功能齐全的ORM框架。
感谢果糖大数据科技团队对SqlSugar的维护和更新。
本文关键字:国产数据库、SqlSugar、ORM、人大金仓、达梦、翰高
SqlSugar 是一款 老牌 .NET 开源ORM框架,由果糖大数据科技团队维护和更新 ,开箱即用最易上手的ORM框架 ,51Job和Boss直招简历数超过 国外框架 Nhibernate PetaPoco, 仅次于Dapper和EF Core , 占Dapper 40% 。
关系型数据库 | MySql、SqlServer、Sqlite、Oracle 、 postgresql、达梦、人大金仓、神通数据库、瀚高、Access 、MySqlConnector、华为 GaussDB 、南大通用 GBase 、Odbc、自定义 |
---|---|
时序数据库 | QuestDb (适合几十亿数据分析,模糊查询,自动分表存储 ,缺点不支持删除) |
列式存储库 | Clickhouse(适用于商业智能领域(BI),缺点大小写必须和库一样,不支持事务) |
即将上线 | Mongodb(mongodb.entities)TDengine、Sybase… |
点击项目引用 >> 右键 Nuget管理
.Net Core 3 & 5 & 6 &7
博主这里因为需要对SqlSugar做一些修改,所以用了源码,结构如下,
public enum DbType
{
MySql ,
SqlServer,
Sqlite,
Oracle,
PostgreSQL,
Dm,
Kdbndp // 人大金仓 只支持.NET CORE
}
appsettings.json配置
"ConnectionStrings": {
"kdbndp": "data source=127.0.0.1;database=test;Port=54321;UID=SYSTEM;PWD=system", //测试版本用人大金仓数据库
"Oracledb": "data source=127.0.0.1/mes;user id=mes_open;password=123456", //Oracle数据库
"MySqldb": "data source=127.0.0.1;database=production;uid=root;pwd=123456",//MySql数据库
"DMdb":"PORT=5236;DATABASE=DAMENG;HOST=127.0.0.1;PASSWORD=SYSDBA;USER ID=SYSDBA",//DM数据库
"HGdb":"PORT=5432;DATABASE=SqlSugar4xTest;HOST=localhost;PASSWORD=haosql;USER ID=postgres",//瀚高数据库
},
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using SqlSugar;
using System;
namespace Sys.Infrastructure.Data
{
///
/// 工作单元实现
///
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();
}
}
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Serilog;
using SqlSugar;
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
}
});
}
///
/// 当数据库操作执行出错时
///
///
private static void OnError(SqlSugarException exception)
{
}
///
/// 当数据库操作执行时
///
///
///
private static void OnLogExecuting(string sql, SugarParameter[] parameters)
{
//StartTime = DateTime.Now;
}
///
/// 当数据库操作执行完毕后
///
///
///
private static void OnLogExecuted(string sql, SugarParameter[] parameters)
{
// EndTime = DateTime.Now;
//CreateHttpSqlLog(sql, parameters);
}
}
}
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Serilog;
using SqlSugar;
using System;
using System.IO;
using System.Linq;
namespace Sys.Infrastructure.Data
{
public class DMOfWork : UnitOfWork, IUnitOfWork
{
public DMOfWork(IConfiguration configuration, IHttpContextAccessor accessor) : base(configuration, accessor)
{
Db = new SqlSugarClient(new ConnectionConfig
{
ConnectionString = configuration.GetConnectionString("DMdb"), //数据库连接在 appsettings.json 中配置
DbType = DbType.DM,
IsAutoCloseConnection = true,
IsShardSameThread = true,
AopEvents = new AopEvents
{
OnLogExecuted = OnLogExecuted,
OnLogExecuting = OnLogExecuting,
OnError = OnError
}
});
}
///
/// 当数据库操作执行出错时
///
///
private static void OnError(SqlSugarException exception)
{
}
///
/// 当数据库操作执行时
///
///
///
private static void OnLogExecuting(string sql, SugarParameter[] parameters)
{
//StartTime = DateTime.Now;
}
///
/// 当数据库操作执行完毕后
///
///
///
private static void OnLogExecuted(string sql, SugarParameter[] parameters)
{
// EndTime = DateTime.Now;
//CreateHttpSqlLog(sql, parameters);
}
}
}
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 MysqlOfWork : UnitOfWork, IUnitOfWork
{
public MysqlOfWork(IConfiguration configuration, IHttpContextAccessor accessor) : base(configuration, accessor)
{
Db = new SqlSugarClient(new ConnectionConfig
{
ConnectionString = configuration.GetConnectionString("Mysqldb"), //数据库连接在 appsettings.json 中配置
DbType = DbType.MySQL,
IsAutoCloseConnection = true,
IsShardSameThread = true,
AopEvents = new AopEvents
{
OnLogExecuted = OnLogExecuted,
OnLogExecuting = OnLogExecuting,
OnError = OnError
}
});
}
///
/// 当数据库操作执行出错时
///
///
private static void OnError(SqlSugarException exception)
{
}
///
/// 当数据库操作执行时
///
///
///
private static void OnLogExecuting(string sql, SugarParameter[] parameters)
{
//StartTime = DateTime.Now;
}
///
/// 当数据库操作执行完毕后
///
///
///
private static void OnLogExecuted(string sql, SugarParameter[] parameters)
{
// EndTime = DateTime.Now;
//CreateHttpSqlLog(sql, parameters);
}
}
}
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 OracleOfWork : UnitOfWork, IUnitOfWork
{
public OracleOfWork(IConfiguration configuration, IHttpContextAccessor accessor) : base(configuration, accessor)
{
Db = new SqlSugarClient(new ConnectionConfig
{
ConnectionString = configuration.GetConnectionString("Oracledb"), //数据库连接在 appsettings.json 中配置
DbType = DbType.Oracle,
IsAutoCloseConnection = true,
IsShardSameThread = true,
AopEvents = new AopEvents
{
OnLogExecuted = OnLogExecuted,
OnLogExecuting = OnLogExecuting,
OnError = OnError
}
});
}
///
/// 当数据库操作执行出错时
///
///
private static void OnError(SqlSugarException exception)
{
}
///
/// 当数据库操作执行时
///
///
///
private static void OnLogExecuting(string sql, SugarParameter[] parameters)
{
//StartTime = DateTime.Now;
}
///
/// 当数据库操作执行完毕后
///
///
///
private static void OnLogExecuted(string sql, SugarParameter[] parameters)
{
// EndTime = DateTime.Now;
//CreateHttpSqlLog(sql, parameters);
}
}
}
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 HGdbOfWork : UnitOfWork, IUnitOfWork
{
public HGdbOfWork(IConfiguration configuration, IHttpContextAccessor accessor) : base(configuration, accessor)
{
Db = new SqlSugarClient(new ConnectionConfig
{
ConnectionString = configuration.GetConnectionString("HGdb"), //数据库连接在 appsettings.json 中配置
DbType = SqlSugar.DbType.PostgreSQL,
IsAutoCloseConnection = true,
MoreSettings=new ConnMoreSettings() {
PgSqlIsAutoToLower=false //数据库存在大写字段的 ,需要把这个设为false ,并且实体和字段名称要一样
},
AopEvents = new AopEvents
{
OnLogExecuting = (sql, p) =>
{
Console.WriteLine(sql);
Console.WriteLine(string.Join(",", p?.Select(it => it.ParameterName + ":" + it.Value)));
}
}
});
}
///
/// 当数据库操作执行出错时
///
///
private static void OnError(SqlSugarException exception)
{
}
///
/// 当数据库操作执行时
///
///
///
private static void OnLogExecuting(string sql, SugarParameter[] parameters)
{
//StartTime = DateTime.Now;
}
///
/// 当数据库操作执行完毕后
///
///
///
private static void OnLogExecuted(string sql, SugarParameter[] parameters)
{
// EndTime = DateTime.Now;
//CreateHttpSqlLog(sql, parameters);
}
}
}
仓储有一套自带的数据库操作方法,比起 db.xx.xxx来说可能更简便些满足一些常用需求, 复杂的功能还是用db.xxx.xxx。
public interface IRepository : IRepository
where TEntity : ApsEntity, new()
{
}
///
/// 人大金仓仓储接口
///
public interface IKdbndpRepository : IRepository
where TEntity : SupplyChanEntity, new()
{
}
///
///达梦仓储接口
///
public interface IDMRepository : IRepository
where TEntity : SupplyChanEntity, new()
{
}
///
/// 翰高仓储接口
///
public interface IHGRepository : IRepository
where TEntity : SupplyChanEntity, new()
{
}
///
/// MySQL仓储接口
///
public interface IMySQLRepository : IRepository
where TEntity : SupplyChanEntity, new()
{
}
///
/// Oracle仓储接口
///
public interface IOracleRepository : IRepository
where TEntity : SupplyChanEntity, new()
{
}
public interface IRepository
where TEntity : Entity, new()
where TUnitOfWork : IUnitOfWork
{
#region 查询
///
/// 是否存在满足指定条件的数据
///
/// 条件表达式
///
bool IsExist(Expression> whereExpression);
///
/// 统计数据条数
///
/// 条件表达式
///
int Count(Expression> whereExpression = null);
///
/// 获取一条数据
///
/// 条件表达式
///
Task SingleAsync(Expression> whereExpression);
///
/// 查询
///
///
Task> QueryAsync();
///
/// 查询
///
/// 查询字符串
///
Task> QueryAsync(string strWhere);
///
/// 查询
///
/// 条件表达式
///
Task> QueryAsync(Expression> whereExpression);
///
/// 查询
///
/// 查询字符串
/// 排序字段,如:Name Asc, Age Desc
///
Task> QueryAsync(string strWhere, string strOrderByFileds);
///
/// 查询
///
/// 条件表达式
/// 排序字段,如:Name Asc, Age Desc
///
Task> QueryAsync(Expression> whereExpression, string strOrderByFileds);
///
/// 查询
///
/// 条件表达式
/// 排序表达式
/// 是否为升序
///
Task> QueryAsync(Expression> whereExpression, Expression> orderByExpression, bool isAsc = true);
///
/// 查询前 N 条数据
///
/// 条件表达式
/// 记录数
/// 排序字段,如:Name Asc, Age Desc
///
Task> TopAsync(
Expression> whereExpression,
int count,
string strOrderByFileds);
///
/// 查询前 N 条数据
///
/// 条件字符串
/// 记录数
/// 排序字段,如:Name Asc, Age Desc
///
Task> TopAsync(
string strWhere,
int count,
string strOrderByFileds);
///
/// 分页查询
///
/// 条件字符串
/// 当前页数
/// 分页大小
/// 排序字段,如:Name Asc, Age Desc
/// 总记录数
///
List Pages(string strWhere, int pageIndex, int pageSize, string strOrderByFileds, out int totalCount);
///
/// 分页查询
///
/// 条件表达式
/// 当前页数
/// 分页大小
/// 排序表达式
/// 是否为升序
/// 总记录数
///
List Pages(Expression> whereExpression,
int pageIndex, int pageSize, Expression> orderByExpression, bool isAsc,
out int totalCount);
///
/// 多表查询
///
/// 实体1
/// 实体2
/// 返回类型
/// 关联表达式 (join1, join2) => new object[] { JoinType.Left, join1.UserNo == join2.UserNo }
/// 返回表达式 (s1, s2) => new { Id =s1.UserNo, Id1 = s2.UserNo }
/// 查询表达式 (w1, w2) => w1.UserNo == "")
///
Task> QueryMuchAsync(
Expression> joinExpression,
Expression> selectExpression,
Expression> whereLambda = null) where T1 : class, new();
///
///多表查询
///
Task> QueryMuchAsync(
Expression> joinExpression,
Expression> selectExpression,
Expression> whereLambda = null) where T1 : class, new();
///
///多表查询
///
Task> QueryMuchAsync(
Expression> joinExpression,
Expression> selectExpression,
Expression> whereLambda = null) where T1 : class, new();
Task> QueryMuchAsync(
Expression> joinExpression,
Expression> selectExpression,
Expression> whereLambda = null) where T1 : class, new();
Task> QueryMuchAsync(
Expression> joinExpression,
Expression> selectExpression,
Expression> whereLambda = null) where T1 : class, new();
#endregion
#region 新增
///
/// 新增
///
/// 实体(集合)
///
Task> AddAsync(params TEntity[] entities);
///
/// 新增
///
/// 实体
/// 指定要插入的列
///
Task AddAsync(TEntity entity, Expression> insertColumns);
///
/// 新增
///
/// 实体集合
/// 指定要插入的列
///
Task> AddAsync(TEntity[] entities, Expression> insertColumns);
#endregion
#region 更新
///
/// 更新
///
/// 实体
/// 指定要更新的列
/// 指定要忽略的列
///
Task UpdateAsync(TEntity entity,
Expression> updateColumns = null,
Expression> ignoreColumns = null);
///
/// 更新
///
/// 实体集合
/// 指定要更新的列
/// 指定要忽略的列
///
Task UpdateAsync(TEntity[] entities,
Expression> updateColumns = null,
Expression> ignoreColumns = null);
///
/// 更新
///
/// 条件表达式
/// 要更新的值(匿名对象)
///
Task UpdateAsync(Expression> whereExpression, dynamic anonymous);
#endregion
#region 删除
///
/// 删除(Support IPhantomEntity)
///
/// 实体(集合)
///
Task DeleteAsync(params TEntity[] entities);
///
/// 删除(Support IPhantomEntity)
///
/// 主键(集合)
///
Task DeleteAsync(params TKey[] ids);
/
/ 删除(Support IPhantomEntity)
/
/ 条件表达式
/
//Task DeleteAsync(Expression> whereExpression);
/
/ 删除(Support IPhantomEntity)
/
/ 条件字符串
/
//Task DeleteAsync(string strWhere);
#endregion
#region 更新或新增
///
/// 更新或插入
/// http://www.codeisbug.com/Doc/8/1172
///
/// 实体
/// 指定要更新或插入的列
/// 指定要忽略的列
///
TEntity UpsertAsync(TEntity entity,
Expression> upsertColumns = null,
Expression> ignoreColumns = null);
///
/// 更新或插入
/// http://www.codeisbug.com/Doc/8/1172
///
/// 实体集合
/// 指定要更新或插入的列
/// 指定要忽略的列
///
Task> UpsertAsync(List entities,
Expression> upsertColumns = null,
Expression> ignoreColumns = null);
///
/// 更新或插入
///
/// 实体
/// 指定要插入的列
/// 指定要忽略的插入列
/// 指定要更新的列
/// 指定要忽略的更新列
///
TEntity UpsertAsync(TEntity entity,
Expression> insertColumns = null,
Expression> ignoreInsertColumns = null,
Expression> updateColumns = null,
Expression> ignoreUpdateColumns = null);
///
/// 更新或插入
///
/// 实体集合
/// 指定要插入的列
/// 指定要忽略的插入列
/// 指定要更新的列
/// 指定要忽略的更新列
///
Task> UpsertAsync(List entities,
Expression> insertColumns = null,
Expression> ignoreInsertColumns = null,
Expression> updateColumns = null,
Expression> ignoreUpdateColumns = null);
#endregion
}
public abstract class Entity
{
[SugarColumn(IsPrimaryKey = true)]
public virtual TKey Id { get; set; }
}
public abstract class KdbndpEntity : Entity, IPhantomEntity
{
public KdbndpEntity()
{
Id = GuidGenerator.Current.Create();
}
///
/// 创建时间
///
[SugarColumn(ColumnName = "create_time", IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
public virtual DateTime CreateTime { get; set; } = DateTime.Now;
///
/// 更新时间
///
[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();
}
}
///
/// 用户表
///
[SugarTable("sys_user")]
public class User : KdbndpEntity
{
///
/// 用户名
///
public string Username { get; set; }
///
/// 昵称
///
public string Nickname { get; set; }
///
/// 手机
///
public string Phone { get; set; }
///
/// 邮箱
///
public string Email { get; set; }
///
/// 密码
///
public string Password { get; set; }
}
///
/// 用户表仓储接口
///
public interface IUserRepository : IKdbndpRepository
{
}
public class UserRepository : Repository, IUserRepository
{
public UserRepository(KdbndpOfWork unitOfWork) : base(unitOfWork)
{
}
}
///
/// 用户表仓储接口
///
public interface IUserRepository : IDMRepository
{
}
public class UserRepository : Repository, IUserRepository
{
public UserRepository(DMOfWork unitOfWork) : base(unitOfWork)
{
}
}
///
/// 用户表仓储接口
///
public interface IUserRepository : IHGRepository
{
}
public class UserRepository : Repository, IUserRepository
{
public UserRepository(HGOfWork unitOfWork) : base(unitOfWork)
{
}
}
public List Query(UserQuery query)
{
return Db.Queryable((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();
}
本文主要介绍了SqlSugar使用工作单元模式操作多个数据库的实战,包括多类型MySQL、人大金仓、达梦等数据,或者同一种数据库的多个库。
文章中出现的任何错误请大家批评指出,一定及时修改。
希望写在这里的小伙伴能给个三连支持!