271 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			271 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
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();
 | 
						||
        }
 | 
						||
    }
 | 
						||
}
 |