Falcon.SugarApi/Falcon.SugarApi/DatabaseDefinitions/SugarDbContext.cs

271 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.Extensions.Logging;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Falcon.SugarApi.DatabaseDefinitions
{
/// <summary>
/// Sugar数据库上下文
/// </summary>
public class SugarDbContext:SqlSugarClient
{
/// <summary>
/// 通过链接配置ConnectionConfig构造SqlSugarClient数据上下文
/// </summary>
/// <param name="config"></param>
/// <param name="logger">日志记录器</param>
public SugarDbContext(SugarConnectionConfig config,ILogger<SugarDbContext> logger) : base(config) {
this.Logger = logger;
if(config.Log) {
this.Aop.OnLogExecuting = (string sql,SugarParameter[] paras) => {
StringBuilder sb = new();
sb.AppendLine(sql);
sb.AppendLine(this.Utilities.SerializeObject(paras.ToDictionary(it => it.ParameterName,it => it.Value)));
this.Logger.LogInformation(sb.ToString());
};
}
}
/// <summary>
/// 日志记录
/// </summary>
public ILogger<SugarDbContext> Logger { get; }
#region
/// <summary>
/// 在数据库中插入数据
/// </summary>
/// <typeparam name="T">数据实体类型</typeparam>
/// <param name="data">要插入的数据列表</param>
/// <param name="createBy">创建人</param>
public void Insert<T>(List<T> data,string createBy) where T : class, new() {
foreach(var i in data) {
if(i is ICreateNew cn) {
cn.CreateNew(createBy);
}
}
try {
this.Insertable(data).ExecuteCommand();
}
catch(Exception ex) {
throw new Exception("SugarDbContext.Insert数据发生异常",ex);
}
}
/// <summary>
/// 在数据库中插入数据
/// </summary>
/// <typeparam name="T">数据模型</typeparam>
/// <param name="data">要插入的数据</param>
/// <param name="createBy">创建人</param>
public void Insert<T>(T data,string createBy) where T : class, new() {
this.Insert(new List<T> { data },createBy);
}
#endregion
#region
/// <summary>
/// 在数据库中更新数据
/// </summary>
/// <typeparam name="T">数据模型</typeparam>
/// <param name="data">要更新的数据</param>
/// <param name="updateBy">更新人</param>
public List<T> Update<T>(List<T> data,string updateBy) where T : class, new() {
foreach(var i in data) {
if(i is IModify cn) {
cn.Modify(updateBy);
}
}
this.Updateable(data).ExecuteCommand();
return data;
}
/// <summary>
/// 修改数据
/// </summary>
/// <typeparam name="T">数据模型</typeparam>
/// <param name="data">要更新的数据</param>
/// <param name="updateBy">更新人</param>
public T Update<T>(T data,string updateBy) where T : class, new() {
this.Update(new List<T> { data },updateBy);
return data;
}
/// <summary>
/// 利用Tracking跟踪并更新数据
/// </summary>
/// <typeparam name="T">要跟踪更新的实体类型</typeparam>
/// <param name="data">要跟踪更新的实体数据</param>
/// <param name="changeValfun">修改实体数据</param>
public void Update<T>(T data,Action<T> changeValfun) where T : class, new() {
if(data == null) return;
this.Tracking(data);
changeValfun?.Invoke(data);
this.Updateable(data).ExecuteCommand();
}
/// <summary>
/// 利用Tracking跟踪并更新数据
/// </summary>
/// <typeparam name="T">要跟踪更新的实体类型</typeparam>
/// <param name="data">要跟踪更新的实体数据</param>
/// <param name="changeValfun">修改实体数据</param>
public async void UpdateAsync<T>(T data,Action<T> changeValfun) where T : class, new() {
if(data == null) return;
this.Tracking(data);
changeValfun?.Invoke(data);
await this.Updateable(data).ExecuteCommandAsync();
}
#endregion
#region
/// <summary>
/// 根据主键调用IDelete实现删除数据记录,软删除并非真正删除数据。
/// </summary>
/// <typeparam name="T">数据实体类型必须继承自SugarTableBase</typeparam>
/// <param name="id">要删除的数据id</param>
/// <param name="deleteBy">删除人</param>
public void Delete<T>(Guid id,string deleteBy) where T : SugarTableBase, new() {
var data = new T();
data.Delete(deleteBy);
this.Updateable<T>()
.Where(m => m.Id == id)
.SetColumns(m => m.Status == data.Status)
.SetColumns(m => m.UpdateBy == data.UpdateBy)
.SetColumns(m => m.UpdateTime == data.UpdateTime)
.ExecuteCommand();
}
/// <summary>
/// 批量软删除对象列表调用实体的IDelete实现删除实体。
/// </summary>
/// <typeparam name="T">实体的类型</typeparam>
/// <param name="data">实体对象列表</param>
/// <param name="deleteBy">删除人</param>
/// <returns>删除后的实体列表</returns>
public List<T> Delete<T>(List<T> data,string deleteBy) where T : class, new() {
foreach(var item in data) {
if(item is IDelete d) {
d.Delete(deleteBy);
}
}
this.Updateable(data).ExecuteCommand();
return data;
}
/// <summary>
/// 对象软删除调用实体的IDelete实现删除实体。
/// </summary>
/// <typeparam name="T">实体的类型</typeparam>
/// <param name="data">实体对象</param>
/// <param name="deleteBy">删除人</param>
/// <returns>删除后的对象</returns>
public T Delete<T>(T data,string deleteBy) where T : class, new() {
this.Delete(new List<T> { data },deleteBy);
return data;
}
#endregion
#region
/// <summary>
/// 已经初始化的类型列表
/// </summary>
private static readonly List<string> InitdTable = new();
/// <summary>
/// 升级数据库表架构并备份表和数据
/// </summary>
/// <param name="types">要升级的表模型</param>
public void UpdateTableStructure(params Type[] types) {
for(int i = 0;i < types.Length;i++) {
var type = types[i];
if(!InitdTable.Any(m => m == type.FullName)) {
this.CodeFirst.BackupTable().SetStringDefaultLength(200).InitTables(type);
if(type.FullName != null) {
InitdTable.Add(type.FullName);
}
}
}
}
/// <summary>
/// 升级数据库表架构并备份表和数据
/// </summary>
/// <typeparam name="TableType">表模型</typeparam>
public void UpdateTableStructure<TableType>() {
this.UpdateTableStructure(typeof(TableType));
}
/// <summary>
/// 升级表架构并在首次建表后插入初始化数据
/// </summary>
/// <typeparam name="TTable">初始化表的模型</typeparam>
/// <param name="tableName">表名</param>
/// <param name="callbackWhenInitTable">表首次创建后执行的回调</param>
public void UpdateTable<TTable>(string tableName,Action<SugarDbContext> callbackWhenInitTable) {
var hasTable = this.DbMaintenance.IsAnyTable(tableName,false);
this.CodeFirst.InitTables<TTable>();
if(!hasTable) {
callbackWhenInitTable(this);
}
}
#endregion
#region
/// <summary>
/// 获取Ado对象执行存储过程
/// </summary>
/// <returns>Ado对象</returns>
public IAdo UseStoredProcedure() {
return this.Ado.UseStoredProcedure();
}
/// <summary>
/// 获取一个Oracle游标类型参数用作返回值
/// </summary>
/// <param name="name">参数名称</param>
/// <returns></returns>
public SugarParameter OracleRefCursor(string name = ":v_data") =>
new(name,null,true) { IsRefCursor = true,DbType = System.Data.DbType.String };
/// <summary>
/// 从对象获取存储过程参数
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="data">参数对象</param>
/// <param name="otherParams">增加其他的参数</param>
/// <returns>参数</returns>
public SugarParameter[] GetParameters<T>(T data,params SugarParameter[] otherParams) {
var result = new List<SugarParameter>();
if(data != null) {
var dict = new Dictionary<string,object>();
foreach(var p in data.GetType().GetProperties()) {
if(p.CanRead) {
dict.Add(p.Name,p.GetValue(data) ?? "");
}
}
result.AddRange(this.Ado.GetParameters(dict).ToArray());
}
if(otherParams != null) {
result.AddRange(otherParams);
}
return result.ToArray();
}
#endregion
/// <summary>
/// 数据库时间
/// </summary>
public DateTime DbDateTime {
get => SqlFunc.GetDate();
}
}
}