添加项目文件。

This commit is contained in:
fuenmao
2025-09-29 13:48:36 +08:00
parent f61e922f0c
commit 5dc1780ef1
407 changed files with 63703 additions and 0 deletions
@@ -0,0 +1,27 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// 通用状态常量
/// </summary>
public class CommonStatusConst
{
/// <summary>
/// 启用
/// </summary>
public const string ENABLE = "ENABLE";
/// <summary>
/// 停用
/// </summary>
public const string DISABLED = "DISABLED";
}
@@ -0,0 +1,67 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// 前端控件作用类型常量
/// </summary>
public class EffTypeConst
{
/// <summary>
/// 输入框
/// </summary>
public const string INPUT = "input";
/// <summary>
/// 文本框
/// </summary>
public const string TEXTAREA = "textarea";
/// <summary>
/// 下拉框
/// </summary>
public const string SELECT = "select";
/// <summary>
/// 单选框
/// </summary>
public const string RADIO = "radio";
/// <summary>
/// 复选框
/// </summary>
public const string CHECKBOX = "checkbox";
/// <summary>
/// 日期选择器
/// </summary>
public const string DATEPICKER = "datepicker";
/// <summary>
/// 时间选择器
/// </summary>
public const string TIMEPICKER = "timepicker";
/// <summary>
/// 数字输入框
/// </summary>
public const string INPUT_NUMBER = "inputNumber";
/// <summary>
/// 滑动数字条
/// </summary>
public const string SLIDER = "slider";
/// <summary>
/// 下拉框
/// </summary>
public const string SWITCH = "switch";
}
@@ -0,0 +1,56 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// SqlSugar系统常量类
/// </summary>
public class SqlSugarConst
{
/// <summary>
/// 默认库ConfigId
/// </summary>
public const string DB_DEFAULT = "SimpleAdmin";
/// <summary>
/// 默认表主键
/// </summary>
public const string DB_PRIMARY_KEY = "Id";
#region 数据库字段类型
/// <summary>
/// varchar(max)
/// </summary>
public const string N_VAR_CHAR_MAX = "nvarchar(max)";
/// <summary>
/// varchar(4000)
/// </summary>
public const string N_VAR_CHAR_4000 = "nvarchar(4000)";
/// <summary>
/// varchar(20)
/// </summary>
public const string N_VAR_CHAR_20 = "nvarchar(20)";
/// <summary>
/// mysql的longtext
/// </summary>
public const string LONG_TEXT = "longtext";
/// <summary>
/// sqlite的text
/// </summary>
public const string TEXT = "text";
#endregion 数据库字段类型
}
+216
View File
@@ -0,0 +1,216 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
using SimpleAdmin.SqlSugar.Filter;
using DbType = SqlSugar.DbType;
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// 数据库上下文对象
/// </summary>
public static class DbContext
{
/// <summary>
/// 读取配置文件中的 ConnectionStrings:SqlSugar 配置节点
/// </summary>
public static readonly List<SqlSugarConfig> DB_CONFIGS = App.GetConfig<List<SqlSugarConfig>>("SqlSugarSettings:ConnectionStrings");
/// <summary>
/// SqlSugar 数据库实例
/// </summary>
public static readonly SqlSugarScope DB = new SqlSugarScope(DB_CONFIGS.Adapt<List<ConnectionConfig>>(), db =>
{
//遍历配置的数据库
DB_CONFIGS.ForEach(it =>
{
var sqlSugarScope = db.GetConnectionScope(it.ConfigId);//获取当前库
MoreSetting(sqlSugarScope, it.DbType);//更多设置
ExternalServicesSetting(sqlSugarScope, it);//实体拓展配置
AopSetting(sqlSugarScope);//aop配置
FilterSetting(sqlSugarScope);//过滤器配置
});
});
/// <summary>
/// 实体拓展配置,自定义类型多库兼容
/// </summary>
/// <param name="db"></param>
/// <param name="config"></param>
private static void ExternalServicesSetting(SqlSugarScopeProvider db, SqlSugarConfig config)
{
db.CurrentConnectionConfig.ConfigureExternalServices = new ConfigureExternalServices
{
// 处理表
EntityNameService = (type, entity) =>
{
if (config.IsUnderLine && !entity.DbTableName.Contains('_'))
entity.DbTableName = UtilMethods.ToUnderLine(entity.DbTableName);// 驼峰转下划线
},
//自定义类型多库兼容
EntityService = (c, p) =>
{
//如果是mysql并且是varchar(max) 已弃用
//if (config.DbType == SqlSugar.DbType.MySql && (p.DataType == SqlSugarConst.NVarCharMax))
//{
// p.DataType = SqlSugarConst.LongText;//转成mysql的longtext
//}
//else if (config.DbType == SqlSugar.DbType.Sqlite && (p.DataType == SqlSugarConst.NVarCharMax))
//{
// p.DataType = SqlSugarConst.Text;//转成sqlite的text
//}
//默认不写IsNullable为非必填
//if (new NullabilityInfoContext().Create(c).WriteState is NullabilityState.Nullable)
// p.IsNullable = true;
if (config.IsUnderLine && !p.IsIgnore && !p.DbColumnName.Contains('_') && p.DbColumnName != "ColumnName")
p.DbColumnName = UtilMethods.ToUnderLine(p.DbColumnName);// 驼峰转下划线
}
};
}
/// <summary>
/// Aop设置
/// </summary>
/// <param name="db"></param>
public static void AopSetting(SqlSugarScopeProvider db)
{
var config = db.CurrentConnectionConfig;
// 设置超时时间
db.Ado.CommandTimeOut = 30;
// 打印SQL语句
db.Aop.OnLogExecuting = (sql, pars) =>
{
//如果不是开发环境就打印sql
if (App.HostEnvironment.IsDevelopment())
{
if (sql.StartsWith("SELECT"))
{
Console.ForegroundColor = ConsoleColor.Green;
WriteSqlLog($"查询{config.ConfigId}库操作");
}
if (sql.StartsWith("UPDATE") || sql.StartsWith("INSERT"))
{
Console.ForegroundColor = ConsoleColor.Blue;
WriteSqlLog($"修改{config.ConfigId}库操作");
}
if (sql.StartsWith("DELETE"))
{
Console.ForegroundColor = ConsoleColor.Red;
WriteSqlLog($"删除{config.ConfigId}库操作");
}
Console.WriteLine(UtilMethods.GetSqlString(config.DbType, sql, pars));
WriteSqlLog($"{config.ConfigId}库操作结束");
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine();
}
};
//异常
db.Aop.OnError = ex =>
{
//如果不是开发环境就打印日志
if (App.WebHostEnvironment.IsDevelopment())
{
if (ex.Parametres == null) return;
Console.ForegroundColor = ConsoleColor.Red;
var pars = db.Utilities.SerializeObject(((SugarParameter[])ex.Parametres).ToDictionary(it => it.ParameterName, it => it.Value));
WriteSqlLog($"{config.ConfigId}库操作异常");
Console.WriteLine(UtilMethods.GetSqlString(config.DbType, ex.Sql, (SugarParameter[])ex.Parametres) + "\r\n");
Console.ForegroundColor = ConsoleColor.White;
}
};
//插入和更新过滤器
db.Aop.DataExecuting = (oldValue, entityInfo) =>
{
// 新增操作
if (entityInfo.OperationType == DataFilterType.InsertByObject)
{
// 主键(long类型)且没有值的---赋值雪花Id
if (entityInfo.EntityColumnInfo.IsPrimarykey && entityInfo.EntityColumnInfo.PropertyInfo.PropertyType == typeof(long))
{
var id = entityInfo.EntityColumnInfo.PropertyInfo.GetValue(entityInfo.EntityValue);
if (id == null || (long)id == 0)
entityInfo.SetValue(CommonUtils.GetSingleId());
}
if (entityInfo.PropertyName == nameof(BaseEntity.CreateTime))
entityInfo.SetValue(DateTime.Now);
if (App.User != null)
{
//创建人和创建机构ID
if (entityInfo.PropertyName == nameof(BaseEntity.CreateUserId))
entityInfo.SetValue(App.User.FindFirst(ClaimConst.USER_ID)?.Value);
if (entityInfo.PropertyName == nameof(BaseEntity.CreateUser))
entityInfo.SetValue(App.User.FindFirst(ClaimConst.ACCOUNT)?.Value);
if (entityInfo.PropertyName == nameof(DataEntityBase.CreateOrgId))
entityInfo.SetValue(App.User.FindFirst(ClaimConst.ORG_ID)?.Value);
}
}
// 更新操作
if (entityInfo.OperationType == DataFilterType.UpdateByObject)
{
//更新时间
if (entityInfo.PropertyName == nameof(BaseEntity.UpdateTime))
entityInfo.SetValue(DateTime.Now);
//更新人
if (App.User != null)
{
if (entityInfo.PropertyName == nameof(BaseEntity.UpdateUserId))
entityInfo.SetValue(App.User?.FindFirst(ClaimConst.USER_ID)?.Value);
if (entityInfo.PropertyName == nameof(BaseEntity.UpdateUser))
entityInfo.SetValue(App.User?.FindFirst(ClaimConst.ACCOUNT)?.Value);
}
}
};
//查询数据转换
db.Aop.DataExecuted = (value, entity) =>
{
};
}
/// <summary>
/// 实体更多配置
/// </summary>
/// <param name="db">db</param>
/// <param name="dbType">数据库类型</param>
private static void MoreSetting(SqlSugarScopeProvider db, DbType dbType)
{
db.CurrentConnectionConfig.MoreSettings = new ConnMoreSettings
{
SqlServerCodeFirstNvarchar = dbType == DbType.SqlServer//设置默认nvarchar
};
}
/// <summary>
/// 过滤器设置
/// </summary>
/// <param name="db"></param>
public static void FilterSetting(SqlSugarScopeProvider db)
{
// 假删除过滤器
LogicDeletedEntityFilter(db);
}
/// <summary>
/// 假删除过滤器
/// </summary>
/// <param name="db"></param>
private static void LogicDeletedEntityFilter(SqlSugarScopeProvider db)
{
// 对实现了IDeletedFilter接口的实体添加过滤条件:只查询未删除的数据
db.QueryFilter.AddTableFilter<IDeletedFilter>(u => u.IsDelete == false);
}
private static void WriteSqlLog(string msg)
{
Console.WriteLine($"=============={msg}==============");
}
}
+134
View File
@@ -0,0 +1,134 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// 仓储模式对象
/// </summary>
[SuppressSniffer]
public class DbRepository<T> : SimpleClient<T> where T : class, new()
{
protected ITenant Tenant;//多租户事务、GetConnection、IsAnyConnection等功能
public DbRepository(ISqlSugarClient context = null) : base(context)//注意这里要有默认值等于null
{
Context = DbContext.DB.GetConnectionScopeWithAttr<T>();//ioc注入的对象
Tenant = DbContext.DB;
}
#region 仓储方法拓展
#region 插入
/// <summary>
/// 批量插入判断走普通导入还是大数据
/// </summary>
/// <param name="data">数据</param>
/// <param name="threshold">阈值</param>
/// <returns></returns>
public virtual async Task<int> InsertOrBulkCopy(List<T> data, int threshold = 10000)
{
if (data.Count > threshold)
return await Context.Fastest<T>().BulkCopyAsync(data);//大数据导入
return await Context.Insertable(data).ExecuteCommandAsync();//普通导入
}
#endregion 插入
#region 列表
/// <summary>
/// 获取列表指定多个字段
/// </summary>
/// <param name="whereExpression">查询条件</param>
/// <param name="selectExpression">查询字段</param>
/// <returns></returns>
public virtual Task<List<T>> GetListAsync(Expression<Func<T, bool>> whereExpression, Expression<Func<T, T>> selectExpression)
{
return Context.Queryable<T>().Where(whereExpression).Select(selectExpression).ToListAsync();
}
/// <summary>
/// 获取列表指定单个字段
/// </summary>
/// <param name="whereExpression">查询条件</param>
/// <param name="selectExpression">查询字段</param>
/// <returns></returns>
public virtual Task<List<string>> GetListAsync(Expression<Func<T, bool>> whereExpression, Expression<Func<T, string>> selectExpression)
{
return Context.Queryable<T>().Where(whereExpression).Select(selectExpression).ToListAsync();
}
/// <summary>
/// 获取列表指定单个字段
/// </summary>
/// <param name="whereExpression">查询条件</param>
/// <param name="selectExpression">查询字段</param>
/// <returns></returns>
public virtual Task<List<long>> GetListAsync(Expression<Func<T, bool>> whereExpression, Expression<Func<T, long>> selectExpression)
{
return Context.Queryable<T>().Where(whereExpression).Select(selectExpression).ToListAsync();
}
#endregion 列表
#region 单查
/// <summary>
/// 获取指定表的单个字段
/// </summary>
/// <param name="whereExpression">查询条件</param>
/// <param name="selectExpression">查询字段</param>
/// <returns></returns>
public virtual Task<string> GetFirstAsync(Expression<Func<T, bool>> whereExpression, Expression<Func<T, string>> selectExpression)
{
return Context.Queryable<T>().Where(whereExpression).Select(selectExpression).FirstAsync();
}
/// <summary>
/// 获取指定表的单个字段
/// </summary>
/// <param name="whereExpression">查询条件</param>
/// <param name="selectExpression">查询字段</param>
/// <returns></returns>
protected virtual Task<long> GetFirstAsync(Expression<Func<T, bool>> whereExpression, Expression<Func<T, long>> selectExpression)
{
return Context.Queryable<T>().Where(whereExpression).Select(selectExpression).FirstAsync();
}
/// <summary>
/// 根据条件查询获取自动分表的单个数据
/// </summary>
/// <param name="whereExpression">条件表达式</param>
/// <param name="startTime">开始时间</param>
/// <param name="endTime">结束时间</param>
/// <returns>实体</returns>
public virtual Task<T> GetFirstSplitTableAsync(Expression<Func<T, bool>> whereExpression, DateTime startTime, DateTime endTime)
{
return Context.Queryable<T>().Where(whereExpression).SplitTable(startTime, endTime).FirstAsync();
}
/// <summary>
/// 根据条件查询获取自动分表的单个数据
/// </summary>
/// <param name="whereExpression">条件表达式</param>
/// <param name="getTableNamesFunc">分表查询表达式</param>
/// <returns>实体</returns>
public virtual Task<T> GetFirstSplitTableAsync(Expression<Func<T, bool>> whereExpression,
Func<List<SplitTableInfo>, IEnumerable<SplitTableInfo>> getTableNamesFunc)
{
return Context.Queryable<T>().Where(whereExpression).SplitTable(getTableNamesFunc).FirstAsync();
}
#endregion 单查
#endregion 仓储方法拓展
}
+22
View File
@@ -0,0 +1,22 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// SqlSugar数据库配置
/// </summary>
public sealed class SqlSugarConfig : ConnectionConfig
{
/// <summary>
/// 是否驼峰转下划线
/// </summary>
public bool IsUnderLine { get; set; }
}
+19
View File
@@ -0,0 +1,19 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// Linq分页泛型集合
/// </summary>
/// <typeparam name="T"></typeparam>
public class LinqPagedList<T> : SqlSugarPagedList<T>
{
}
+95
View File
@@ -0,0 +1,95 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
using SimpleAdmin.SqlSugar.Filter;
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// 主键实体基类
/// </summary>
public abstract class PrimaryKeyEntity
{
/// <summary>
/// 主键Id
/// </summary>
[SugarColumn(ColumnDescription = "Id", IsPrimaryKey = true)]
public virtual long Id { get; set; }
/// <summary>
/// 拓展信息
/// </summary>
[SugarColumn(ColumnName = "ExtJson", ColumnDescription = "扩展信息", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
public virtual string ExtJson { get; set; }
}
/// <summary>
/// 框架实体基类
/// </summary>
public class BaseEntity : PrimaryKeyEntity,IDeletedFilter
{
[SugarColumn(ColumnName = "Status", ColumnDescription = "状态", Length = 20, DefaultValue = CommonStatusConst.ENABLE,
IsNullable = true)]
public virtual string Status { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[SugarColumn(ColumnDescription = "创建时间", IsOnlyIgnoreUpdate = true, IsNullable = true)]
public virtual DateTime? CreateTime { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[SugarColumn(ColumnDescription = "更新时间", IsOnlyIgnoreInsert = true, IsNullable = true)]
public virtual DateTime? UpdateTime { get; set; }
/// <summary>
/// 创建者Id
/// </summary>
[SugarColumn(ColumnDescription = "创建者Id", IsOnlyIgnoreUpdate = true, IsNullable = true)]
public virtual long? CreateUserId { get; set; }
/// <summary>
/// 修改者Id
/// </summary>
[SugarColumn(ColumnDescription = "修改者Id", IsOnlyIgnoreInsert = true, IsNullable = true)]
public virtual long? UpdateUserId { get; set; }
/// <summary>
/// 创建人
/// </summary>
[SugarColumn(ColumnDescription = "创建人", IsOnlyIgnoreUpdate = true, IsNullable = true)]
public virtual string CreateUser { get; set; }
/// <summary>
/// 更新人
/// </summary>
[SugarColumn(ColumnDescription = "更新人", IsOnlyIgnoreInsert = true, IsNullable = true)]
public virtual string UpdateUser { get; set; }
/// <summary>
/// 软删除
/// </summary>
[SugarColumn(ColumnDescription = "软删除", IsNullable = true)]
public virtual bool IsDelete { get; set; }
}
/// <summary>
/// 业务数据实体基类(数据权限)
/// </summary>
public abstract class DataEntityBase : BaseEntity
{
/// <summary>
/// 创建者部门Id
/// </summary>
[SugarColumn(ColumnDescription = "创建者部门Id", IsOnlyIgnoreUpdate = true, IsNullable = true)]
public virtual long CreateOrgId { get; set; }
}
@@ -0,0 +1,24 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// 实体种子数据接口
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public interface ISqlSugarEntitySeedData<TEntity> where TEntity : class, new()
{
/// <summary>
/// 种子数据
/// </summary>
/// <returns></returns>
IEnumerable<TEntity> SeedData();
}
@@ -0,0 +1,190 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// SqlSugar分页拓展类
/// </summary>
public static class SqlSugarPageExtension
{
/// <summary>
/// SqlSugar分页扩展
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="queryable"></param>
/// <param name="pageNum"></param>
/// <param name="pageSize"></param>
/// <returns></returns>
public static SqlSugarPagedList<TEntity> ToPagedList<TEntity>(this ISugarQueryable<TEntity> queryable, int pageNum, int pageSize)
{
var total = 0;
var list = queryable.ToPageList(pageSize, pageNum, ref total);
var pages = (int)Math.Ceiling(total / (double)pageSize);
return new SqlSugarPagedList<TEntity>
{
PageNum = pageSize,
PageSize = pageNum,
List = list,
Total = total,
Pages = pages,
HasNextPages = pageSize < pages,
HasPrevPages = pageSize - 1 > 0
};
}
/// <summary>
/// SqlSugar分页扩展
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="queryable"></param>
/// <param name="pageNum"></param>
/// <param name="pageSize"></param>
/// <returns></returns>
public static async Task<SqlSugarPagedList<TEntity>> ToPagedListAsync<TEntity>(this ISugarQueryable<TEntity> queryable, int pageNum, int pageSize)
{
RefAsync<int> totalCount = 0;
var list = await queryable.ToPageListAsync(pageNum, pageSize, totalCount);
var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
return new SqlSugarPagedList<TEntity>
{
PageNum = pageNum,
PageSize = pageSize,
List = list,
Total = (int)totalCount,
Pages = totalPages,
HasNextPages = pageNum < totalPages,
HasPrevPages = pageNum - 1 > 0
};
}
/// <summary>
/// SqlSugar分页扩展
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="queryable"></param>
/// <param name="pageNum"></param>
/// <param name="pageSize"></param>
/// <param name="expression"></param>
/// <returns></returns>
public static SqlSugarPagedList<TResult> ToPagedList<TEntity, TResult>(this ISugarQueryable<TEntity> queryable, int pageNum, int pageSize,
Expression<Func<TEntity, TResult>> expression)
{
var totalCount = 0;
var items = queryable.ToPageList(pageNum, pageSize, ref totalCount, expression);
var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
return new SqlSugarPagedList<TResult>
{
PageNum = pageNum,
PageSize = pageSize,
List = items,
Total = totalCount,
Pages = totalPages,
HasNextPages = pageNum < totalPages,
HasPrevPages = pageNum - 1 > 0
};
}
/// <summary>
/// SqlSugar分页扩展
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TResult"></typeparam>
/// <param name="queryable"></param>
/// <param name="pageNum"></param>
/// <param name="pageSize"></param>
/// <param name="expression"></param>
/// <returns></returns>
public static async Task<SqlSugarPagedList<TResult>> ToPagedListAsync<TEntity, TResult>(this ISugarQueryable<TEntity> queryable, int pageNum,
int pageSize,
Expression<Func<TEntity, TResult>> expression)
{
RefAsync<int> totalCount = 0;
var items = await queryable.ToPageListAsync(pageNum, pageSize, totalCount, expression);
var totalPages = (int)Math.Ceiling(totalCount / (double)pageSize);
return new SqlSugarPagedList<TResult>
{
PageNum = pageNum,
PageSize = pageSize,
List = items,
Total = (int)totalCount,
Pages = totalPages,
HasNextPages = pageNum < totalPages,
HasPrevPages = pageNum - 1 > 0
};
}
/// <summary>
/// 分页查询
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">数据列表</param>
/// <param name="pageNum">当前页</param>
/// <param name="pageSize">每页数量</param>
/// <returns>分页集合</returns>
public static LinqPagedList<T> LinqPagedList<T>(this List<T> list, int pageNum, int pageSize)
{
var result = list.ToPagedList(pageNum, pageSize);//获取分页
//格式化
return new LinqPagedList<T>
{
PageNum = pageNum,
PageSize = result.PageSize,
List = result.Data,
Total = result.TotalCount,
Pages = result.TotalPages,
HasNextPages = result.HasNext,
HasPrevPages = result.HasPrev
};
}
}
/// <summary>
/// SqlSugar 分页泛型集合
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public class SqlSugarPagedList<TEntity>
{
/// <summary>
/// 页码
/// </summary>
public int PageNum { get; set; }
/// <summary>
/// 数量
/// </summary>
public int PageSize { get; set; }
/// <summary>
/// 总条数
/// </summary>
public int Total { get; set; }
/// <summary>
/// 总页数
/// </summary>
public int Pages { get; set; }
/// <summary>
/// 当前页集合
/// </summary>
public IEnumerable<TEntity> List { get; set; }
/// <summary>
/// 是否有上一页
/// </summary>
public bool HasPrevPages { get; set; }
/// <summary>
/// 是否有下一页
/// </summary>
public bool HasNextPages { get; set; }
}
@@ -0,0 +1,79 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// SqlSugar 事务和工作单元
/// </summary>
public sealed class SqlSugarUnitOfWork : IUnitOfWork
{
/// <summary>
/// SqlSugar 对象
/// </summary>
private readonly ISqlSugarClient _sqlSugarClient;
private readonly ILogger<SqlSugarUnitOfWork> _logger;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="sqlSugarClient"></param>
/// <param name="logger"></param>
public SqlSugarUnitOfWork(ISqlSugarClient sqlSugarClient, ILogger<SqlSugarUnitOfWork> logger)
{
_sqlSugarClient = sqlSugarClient;
_logger = logger;
}
/// <summary>
/// 开启工作单元处理
/// </summary>
/// <param name="context"></param>
/// <param name="unitOfWork"></param>
/// <exception cref="NotImplementedException"></exception>
public void BeginTransaction(FilterContext context, UnitOfWorkAttribute unitOfWork)
{
_sqlSugarClient.AsTenant().BeginTran();
}
/// <summary>
/// 提交工作单元处理
/// </summary>
/// <param name="resultContext"></param>
/// <param name="unitOfWork"></param>
/// <exception cref="NotImplementedException"></exception>
public void CommitTransaction(FilterContext resultContext, UnitOfWorkAttribute unitOfWork)
{
_sqlSugarClient.AsTenant().CommitTran();
}
/// <summary>
/// 回滚工作单元处理
/// </summary>
/// <param name="resultContext"></param>
/// <param name="unitOfWork"></param>
/// <exception cref="NotImplementedException"></exception>
public void RollbackTransaction(FilterContext resultContext, UnitOfWorkAttribute unitOfWork)
{
_sqlSugarClient.AsTenant().RollbackTran();
}
/// <summary>
/// 执行完毕(无论成功失败)
/// </summary>
/// <param name="context"></param>
/// <param name="resultContext"></param>
/// <exception cref="NotImplementedException"></exception>
public void OnCompleted(FilterContext context, FilterContext resultContext)
{
_sqlSugarClient.Dispose();
}
}
@@ -0,0 +1,29 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SimpleAdmin.SqlSugar.Filter
{
/// <summary>
/// 假删除接口过滤器
/// </summary>
public interface IDeletedFilter
{
/// <summary>
/// 软删除
/// </summary>
bool IsDelete { get; set; }
}
}
+31
View File
@@ -0,0 +1,31 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
global using MoYu;
global using MoYu.DependencyInjection;
global using MoYu.FriendlyException;
global using Mapster;
global using Masuit.Tools;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Hosting;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Hosting;
global using Microsoft.Extensions.Logging;
global using NewLife.Serialization;
global using SimpleAdmin.Core;
global using SimpleAdmin.Core.Utils;
global using SimpleTool;
global using SqlSugar;
global using System.Data;
global using System.Linq.Expressions;
global using System.Reflection;
global using Masuit.Tools.Models;
global using MoYu.DatabaseAccessor;
global using Microsoft.AspNetCore.Mvc.Filters;
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="SqlSugarCore" Version="5.1.4.198" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SimpleAdmin.Core\SimpleAdmin.Core.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="SqlSugar.Development.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="SqlSugar.Production.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Remove="CodeFirst\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="CodeFirst\**" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Remove="CodeFirst\**" />
</ItemGroup>
</Project>
@@ -0,0 +1,665 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>SimpleAdmin.SqlSugar</name>
</assembly>
<members>
<member name="T:SimpleAdmin.SqlSugar.CommonStatusConst">
<summary>
通用状态常量
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.CommonStatusConst.ENABLE">
<summary>
启用
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.CommonStatusConst.DISABLED">
<summary>
停用
</summary>
</member>
<member name="T:SimpleAdmin.SqlSugar.EffTypeConst">
<summary>
前端控件作用类型常量
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.EffTypeConst.INPUT">
<summary>
输入框
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.EffTypeConst.TEXTAREA">
<summary>
文本框
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.EffTypeConst.SELECT">
<summary>
下拉框
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.EffTypeConst.RADIO">
<summary>
单选框
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.EffTypeConst.CHECKBOX">
<summary>
复选框
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.EffTypeConst.DATEPICKER">
<summary>
日期选择器
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.EffTypeConst.TIMEPICKER">
<summary>
时间选择器
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.EffTypeConst.INPUT_NUMBER">
<summary>
数字输入框
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.EffTypeConst.SLIDER">
<summary>
滑动数字条
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.EffTypeConst.SWITCH">
<summary>
下拉框
</summary>
</member>
<member name="T:SimpleAdmin.SqlSugar.SqlSugarConst">
<summary>
SqlSugar系统常量类
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.SqlSugarConst.DB_DEFAULT">
<summary>
默认库ConfigId
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.SqlSugarConst.DB_PRIMARY_KEY">
<summary>
默认表主键
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.SqlSugarConst.N_VAR_CHAR_MAX">
<summary>
varchar(max)
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.SqlSugarConst.N_VAR_CHAR_4000">
<summary>
varchar(4000)
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.SqlSugarConst.N_VAR_CHAR_20">
<summary>
varchar(20)
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.SqlSugarConst.LONG_TEXT">
<summary>
mysql的longtext
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.SqlSugarConst.TEXT">
<summary>
sqlite的text
</summary>
</member>
<member name="T:SimpleAdmin.SqlSugar.DbContext">
<summary>
数据库上下文对象
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.DbContext.DB_CONFIGS">
<summary>
读取配置文件中的 ConnectionStrings:SqlSugar 配置节点
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.DbContext.DB">
<summary>
SqlSugar 数据库实例
</summary>
</member>
<member name="M:SimpleAdmin.SqlSugar.DbContext.ExternalServicesSetting(SqlSugar.SqlSugarScopeProvider,SimpleAdmin.SqlSugar.SqlSugarConfig)">
<summary>
实体拓展配置,自定义类型多库兼容
</summary>
<param name="db"></param>
<param name="config"></param>
</member>
<member name="M:SimpleAdmin.SqlSugar.DbContext.AopSetting(SqlSugar.SqlSugarScopeProvider)">
<summary>
Aop设置
</summary>
<param name="db"></param>
</member>
<member name="M:SimpleAdmin.SqlSugar.DbContext.MoreSetting(SqlSugar.SqlSugarScopeProvider,SqlSugar.DbType)">
<summary>
实体更多配置
</summary>
<param name="db">db</param>
<param name="dbType">数据库类型</param>
</member>
<member name="M:SimpleAdmin.SqlSugar.DbContext.FilterSetting(SqlSugar.SqlSugarScopeProvider)">
<summary>
过滤器设置
</summary>
<param name="db"></param>
</member>
<member name="M:SimpleAdmin.SqlSugar.DbContext.LogicDeletedEntityFilter(SqlSugar.SqlSugarScopeProvider)">
<summary>
假删除过滤器
</summary>
<param name="db"></param>
</member>
<member name="T:SimpleAdmin.SqlSugar.DbRepository`1">
<summary>
仓储模式对象
</summary>
</member>
<member name="M:SimpleAdmin.SqlSugar.DbRepository`1.InsertOrBulkCopy(System.Collections.Generic.List{`0},System.Int32)">
<summary>
批量插入判断走普通导入还是大数据
</summary>
<param name="data">数据</param>
<param name="threshold">阈值</param>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.DbRepository`1.GetListAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}},System.Linq.Expressions.Expression{System.Func{`0,`0}})">
<summary>
获取列表指定多个字段
</summary>
<param name="whereExpression">查询条件</param>
<param name="selectExpression">查询字段</param>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.DbRepository`1.GetListAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}},System.Linq.Expressions.Expression{System.Func{`0,System.String}})">
<summary>
获取列表指定单个字段
</summary>
<param name="whereExpression">查询条件</param>
<param name="selectExpression">查询字段</param>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.DbRepository`1.GetListAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}},System.Linq.Expressions.Expression{System.Func{`0,System.Int64}})">
<summary>
获取列表指定单个字段
</summary>
<param name="whereExpression">查询条件</param>
<param name="selectExpression">查询字段</param>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.DbRepository`1.GetFirstAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}},System.Linq.Expressions.Expression{System.Func{`0,System.String}})">
<summary>
获取指定表的单个字段
</summary>
<param name="whereExpression">查询条件</param>
<param name="selectExpression">查询字段</param>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.DbRepository`1.GetFirstAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}},System.Linq.Expressions.Expression{System.Func{`0,System.Int64}})">
<summary>
获取指定表的单个字段
</summary>
<param name="whereExpression">查询条件</param>
<param name="selectExpression">查询字段</param>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.DbRepository`1.GetFirstSplitTableAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}},System.DateTime,System.DateTime)">
<summary>
根据条件查询获取自动分表的单个数据
</summary>
<param name="whereExpression">条件表达式</param>
<param name="startTime">开始时间</param>
<param name="endTime">结束时间</param>
<returns>实体</returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.DbRepository`1.GetFirstSplitTableAsync(System.Linq.Expressions.Expression{System.Func{`0,System.Boolean}},System.Func{System.Collections.Generic.List{SqlSugar.SplitTableInfo},System.Collections.Generic.IEnumerable{SqlSugar.SplitTableInfo}})">
<summary>
根据条件查询获取自动分表的单个数据
</summary>
<param name="whereExpression">条件表达式</param>
<param name="getTableNamesFunc">分表查询表达式</param>
<returns>实体</returns>
</member>
<member name="T:SimpleAdmin.SqlSugar.SqlSugarConfig">
<summary>
SqlSugar数据库配置
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarConfig.IsUnderLine">
<summary>
是否驼峰转下划线
</summary>
</member>
<member name="T:SimpleAdmin.SqlSugar.LinqPagedList`1">
<summary>
Linq分页泛型集合
</summary>
<typeparam name="T"></typeparam>
</member>
<member name="T:SimpleAdmin.SqlSugar.PrimaryKeyEntity">
<summary>
主键实体基类
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.PrimaryKeyEntity.Id">
<summary>
主键Id
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.PrimaryKeyEntity.ExtJson">
<summary>
拓展信息
</summary>
</member>
<member name="T:SimpleAdmin.SqlSugar.BaseEntity">
<summary>
框架实体基类
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.BaseEntity.CreateTime">
<summary>
创建时间
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.BaseEntity.UpdateTime">
<summary>
更新时间
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.BaseEntity.CreateUserId">
<summary>
创建者Id
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.BaseEntity.UpdateUserId">
<summary>
修改者Id
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.BaseEntity.CreateUser">
<summary>
创建人
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.BaseEntity.UpdateUser">
<summary>
更新人
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.BaseEntity.IsDelete">
<summary>
软删除
</summary>
</member>
<member name="T:SimpleAdmin.SqlSugar.DataEntityBase">
<summary>
业务数据实体基类(数据权限)
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.DataEntityBase.CreateOrgId">
<summary>
创建者部门Id
</summary>
</member>
<member name="T:SimpleAdmin.SqlSugar.ISqlSugarEntitySeedData`1">
<summary>
实体种子数据接口
</summary>
<typeparam name="TEntity"></typeparam>
</member>
<member name="M:SimpleAdmin.SqlSugar.ISqlSugarEntitySeedData`1.SeedData">
<summary>
种子数据
</summary>
<returns></returns>
</member>
<member name="T:SimpleAdmin.SqlSugar.SqlSugarPageExtension">
<summary>
SqlSugar分页拓展类
</summary>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarPageExtension.ToPagedList``1(SqlSugar.ISugarQueryable{``0},System.Int32,System.Int32)">
<summary>
SqlSugar分页扩展
</summary>
<typeparam name="TEntity"></typeparam>
<param name="queryable"></param>
<param name="pageNum"></param>
<param name="pageSize"></param>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarPageExtension.ToPagedListAsync``1(SqlSugar.ISugarQueryable{``0},System.Int32,System.Int32)">
<summary>
SqlSugar分页扩展
</summary>
<typeparam name="TEntity"></typeparam>
<param name="queryable"></param>
<param name="pageNum"></param>
<param name="pageSize"></param>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarPageExtension.ToPagedList``2(SqlSugar.ISugarQueryable{``0},System.Int32,System.Int32,System.Linq.Expressions.Expression{System.Func{``0,``1}})">
<summary>
SqlSugar分页扩展
</summary>
<typeparam name="TEntity"></typeparam>
<typeparam name="TResult"></typeparam>
<param name="queryable"></param>
<param name="pageNum"></param>
<param name="pageSize"></param>
<param name="expression"></param>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarPageExtension.ToPagedListAsync``2(SqlSugar.ISugarQueryable{``0},System.Int32,System.Int32,System.Linq.Expressions.Expression{System.Func{``0,``1}})">
<summary>
SqlSugar分页扩展
</summary>
<typeparam name="TEntity"></typeparam>
<typeparam name="TResult"></typeparam>
<param name="queryable"></param>
<param name="pageNum"></param>
<param name="pageSize"></param>
<param name="expression"></param>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarPageExtension.LinqPagedList``1(System.Collections.Generic.List{``0},System.Int32,System.Int32)">
<summary>
分页查询
</summary>
<typeparam name="T"></typeparam>
<param name="list">数据列表</param>
<param name="pageNum">当前页</param>
<param name="pageSize">每页数量</param>
<returns>分页集合</returns>
</member>
<member name="T:SimpleAdmin.SqlSugar.SqlSugarPagedList`1">
<summary>
SqlSugar 分页泛型集合
</summary>
<typeparam name="TEntity"></typeparam>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarPagedList`1.PageNum">
<summary>
页码
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarPagedList`1.PageSize">
<summary>
数量
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarPagedList`1.Total">
<summary>
总条数
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarPagedList`1.Pages">
<summary>
总页数
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarPagedList`1.List">
<summary>
当前页集合
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarPagedList`1.HasPrevPages">
<summary>
是否有上一页
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarPagedList`1.HasNextPages">
<summary>
是否有下一页
</summary>
</member>
<member name="T:SimpleAdmin.SqlSugar.SqlSugarUnitOfWork">
<summary>
SqlSugar 事务和工作单元
</summary>
</member>
<member name="F:SimpleAdmin.SqlSugar.SqlSugarUnitOfWork._sqlSugarClient">
<summary>
SqlSugar 对象
</summary>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarUnitOfWork.#ctor(SqlSugar.ISqlSugarClient,Microsoft.Extensions.Logging.ILogger{SimpleAdmin.SqlSugar.SqlSugarUnitOfWork})">
<summary>
构造函数
</summary>
<param name="sqlSugarClient"></param>
<param name="logger"></param>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarUnitOfWork.BeginTransaction(Microsoft.AspNetCore.Mvc.Filters.FilterContext,MoYu.DatabaseAccessor.UnitOfWorkAttribute)">
<summary>
开启工作单元处理
</summary>
<param name="context"></param>
<param name="unitOfWork"></param>
<exception cref="T:System.NotImplementedException"></exception>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarUnitOfWork.CommitTransaction(Microsoft.AspNetCore.Mvc.Filters.FilterContext,MoYu.DatabaseAccessor.UnitOfWorkAttribute)">
<summary>
提交工作单元处理
</summary>
<param name="resultContext"></param>
<param name="unitOfWork"></param>
<exception cref="T:System.NotImplementedException"></exception>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarUnitOfWork.RollbackTransaction(Microsoft.AspNetCore.Mvc.Filters.FilterContext,MoYu.DatabaseAccessor.UnitOfWorkAttribute)">
<summary>
回滚工作单元处理
</summary>
<param name="resultContext"></param>
<param name="unitOfWork"></param>
<exception cref="T:System.NotImplementedException"></exception>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarUnitOfWork.OnCompleted(Microsoft.AspNetCore.Mvc.Filters.FilterContext,Microsoft.AspNetCore.Mvc.Filters.FilterContext)">
<summary>
执行完毕(无论成功失败)
</summary>
<param name="context"></param>
<param name="resultContext"></param>
<exception cref="T:System.NotImplementedException"></exception>
</member>
<member name="T:SimpleAdmin.SqlSugar.Filter.IDeletedFilter">
<summary>
假删除接口过滤器
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.Filter.IDeletedFilter.IsDelete">
<summary>
软删除
</summary>
</member>
<member name="T:SimpleAdmin.SqlSugar.Startup">
<summary>
AppStartup启动类
</summary>
</member>
<member name="M:SimpleAdmin.SqlSugar.Startup.ConfigureServices(Microsoft.Extensions.DependencyInjection.IServiceCollection)">
<summary>
ConfigureServices中不能解析服务,比如App.GetService(),尤其是不能在ConfigureServices中获取诸如缓存等数据进行初始化,应该在Configure中进行
服务都还没初始化完成,会导致内存中存在多份 IOC 容器!!
正确应该在 Configure 中,这个时候服务(IServiceCollection 已经完成 BuildServiceProvider() 操作了
</summary>
<param name="services"></param>
</member>
<member name="M:SimpleAdmin.SqlSugar.Startup.CheckSameConfigId">
<summary>
检查是否有相同的ConfigId
</summary>
<returns></returns>
</member>
<member name="T:SimpleAdmin.SqlSugar.CodeFirstUtils">
<summary>
CodeFirst功能类
</summary>
</member>
<member name="M:SimpleAdmin.SqlSugar.CodeFirstUtils.CodeFirst(SimpleAdmin.Core.BaseOptions,System.String)">
<summary>
CodeFirst生成数据库表结构和种子数据
</summary>
<param name="options">codefirst选项</param>
<param name="assemblyName">程序集名称</param>
</member>
<member name="M:SimpleAdmin.SqlSugar.CodeFirstUtils.InitTable(System.String)">
<summary>
初始化数据库表结构
</summary>
<param name="assemblyName">程序集名称</param>
</member>
<member name="M:SimpleAdmin.SqlSugar.CodeFirstUtils.InitSeedData(System.String)">
<summary>
初始化种子数据
</summary>
<param name="assemblyName">程序集名称</param>
</member>
<member name="M:SimpleAdmin.SqlSugar.CodeFirstUtils.HasImplementedRawGeneric(System.Type,System.Type)">
<summary>
判断类型是否实现某个泛型
</summary>
<param name="type">类型</param>
<param name="generic">泛型类型</param>
<returns>bool</returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.CodeFirstUtils.ToDataTable``1(System.Collections.Generic.List{``0})">
<summary>
List转DataTable
</summary>
<typeparam name="T"></typeparam>
<param name="list"></param>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.CodeFirstUtils.IsIgnoreColumn(System.Reflection.PropertyInfo)">
<summary>
排除SqlSugar忽略的列
</summary>
<param name="pi"></param>
<returns></returns>
</member>
<member name="T:SimpleAdmin.SqlSugar.SqlSugarColumnInfo">
<summary>
SqlSugar字段信息
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarColumnInfo.ColumnName">
<summary>
字段名称
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarColumnInfo.IsPrimaryKey">
<summary>
是否主键
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarColumnInfo.DataType">
<summary>
字段类型
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarColumnInfo.ColumnDescription">
<summary>
字段注释
</summary>
</member>
<member name="T:SimpleAdmin.SqlSugar.SqlSugarTableInfo">
<summary>
SqlSugar表信息
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarTableInfo.ConfigId">
<summary>
所属库
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarTableInfo.TableName">
<summary>
表名称
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarTableInfo.EntityName">
<summary>
实体名
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarTableInfo.TableDescription">
<summary>
表注释
</summary>
</member>
<member name="P:SimpleAdmin.SqlSugar.SqlSugarTableInfo.Columns">
<summary>
表字段
</summary>
</member>
<member name="T:SimpleAdmin.SqlSugar.SeedDataUtil">
<summary>
种子数据工具类
</summary>
</member>
<member name="T:SimpleAdmin.SqlSugar.SeedDataRecords`1">
<summary>
种子数据格式实体类,遵循Navicat导出json格式
</summary>
<typeparam name="T"></typeparam>
</member>
<member name="P:SimpleAdmin.SqlSugar.SeedDataRecords`1.Records">
<summary>
数据
</summary>
</member>
<member name="T:SimpleAdmin.SqlSugar.SqlSugarUtils">
<summary>
SqlSugar通用功能
</summary>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarUtils.GetTablesByAttribute``1">
<summary>
根据特性获取所有表信息
</summary>
<typeparam name="T"></typeparam>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarUtils.GetTableColumns(System.String,System.String)">
<summary>
获取字段信息
</summary>
<param name="configId"></param>
<param name="tableName"></param>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarUtils.ConvertDataType(System.String)">
<summary>
数据库字段类型转.NET类型
</summary>
<param name="dataType">字段类型</param>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarUtils.DataTypeToEff(System.String)">
<summary>
数据类型转显示类型
</summary>
<param name="dataType"></param>
<returns></returns>
</member>
<member name="M:SimpleAdmin.SqlSugar.SqlSugarUtils.IsCommonColumn(System.String)">
<summary>
是否通用字段
</summary>
<param name="columnName">字段名</param>
<returns></returns>
</member>
</members>
</doc>
@@ -0,0 +1,21 @@
{
//sqlSugar设置
"SqlSugarSettings": {
//SqlSugar连接字符串配置
"ConnectionStrings": [
{
"ConfigId": "SimpleAdmin", //租户ID
"ConnectionString": "AllowLoadLocalInfile=true;Server=58.17.132.2;User ID=admin;Password=so^867z$4S;Port=16306;Database=weibingjutest;CharSet=utf8mb4;pooling=true;SslMode=None;min pool size=1;Connection Timeout=30;Pooling=false", //连接字符串
"DbType": "MySql", //数据库类型
"IsAutoCloseConnection": true //是否自动释放
}
// {
// "ConfigId": "SimpleAdmin", //租户ID
// "ConnectionString": "Server=192.168.1.16;Database=SimpleAdmin;User=sa;Password=123456;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=True;", //连接字符串
// "DbType": "SqlServer", //数据库类型
// "IsAutoCloseConnection": true, //是否自动释放
// "IsUnderLine": false //是否驼峰转下划线
// }
]
}
}
@@ -0,0 +1,20 @@
{
//sqlsugar设置
"SqlSugarSettings": {
//SqlSugar连接字符串配置
"ConnectionStrings": [
{
"ConfigId": "SimpleAdmin", //租户ID
"ConnectionString": "AllowLoadLocalInfile=true;Server=58.17.132.2;User ID=admin;Password=so^867z$4S;Port=16306;Database=WeiBingJu;CharSet=utf8mb4;pooling=true;SslMode=None;min pool size=1;Connection Timeout=30;Pooling=false", //连接字符串
"DbType": "MySql", //数据库类型
"IsAutoCloseConnection": true //是否自动释放
}
// {
// "ConfigId": "SimpleAdmin", //租户ID
// "ConnectionString": "Server=192.168.1.16;Database=SimpleAdmin;User=sa;Password=123456;MultipleActiveResultSets=True;", //连接字符串
// "DbType": "SqlServer", //数据库类型
// "IsAutoCloseConnection": true, //是否自动释放
// }
]
}
}
+53
View File
@@ -0,0 +1,53 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// AppStartup启动类
/// </summary>
[AppStartup(98)]
public class Startup : AppStartup
{
/// <summary>
/// ConfigureServices中不能解析服务,比如App.GetService(),尤其是不能在ConfigureServices中获取诸如缓存等数据进行初始化,应该在Configure中进行
/// 服务都还没初始化完成,会导致内存中存在多份 IOC 容器!!
/// 正确应该在 Configure 中,这个时候服务(IServiceCollection 已经完成 BuildServiceProvider() 操作了
/// </summary>
/// <param name="services"></param>
public void ConfigureServices(IServiceCollection services)
{
//检查ConfigId
CheckSameConfigId();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//遍历配置
DbContext.DB_CONFIGS.ForEach(it =>
{
var connection = DbContext.DB.GetConnection(it.ConfigId);//获取数据库连接对象
connection.DbMaintenance.CreateDatabase();//创建数据库,如果存在则不创建
});
}
/// <summary>
/// 检查是否有相同的ConfigId
/// </summary>
/// <returns></returns>
private static void CheckSameConfigId()
{
var configIdGroup = DbContext.DB_CONFIGS.GroupBy(it => it.ConfigId).ToList();
foreach (var configId in configIdGroup)
{
if (configId.ToList().Count > 1) throw Oops.Oh($"SqlSugar连接配置ConfigId:{configId.Key}重复了");
}
}
}
@@ -0,0 +1,199 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
using System.Collections;
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// CodeFirst功能类
/// </summary>
[SuppressSniffer]
public static class CodeFirstUtils
{
/// <summary>
/// CodeFirst生成数据库表结构和种子数据
/// </summary>
/// <param name="options">codefirst选项</param>
/// <param name="assemblyName">程序集名称</param>
public static void CodeFirst(BaseOptions options, string assemblyName)
{
var appName = assemblyName.Split(",")[0];
if (options.InitTable)//如果需要初始化表结构
{
Console.WriteLine($"开始初始化{appName}数据库表结构");
InitTable(assemblyName);
}
if (options.InitSeedData)
{
Console.WriteLine($"开始初始化{appName}数据库种子数据");
InitSeedData(assemblyName);
}
}
/// <summary>
/// 初始化数据库表结构
/// </summary>
/// <param name="assemblyName">程序集名称</param>
private static void InitTable(string assemblyName)
{
// 获取所有实体表-初始化表结构
var entityTypes = App.EffectiveTypes.Where(u =>
!u.IsInterface && !u.IsAbstract && u.IsClass && u.IsDefined(typeof(SugarTable), false) && u.Assembly.FullName == assemblyName);
if (!entityTypes.Any()) return;//没有就退出
foreach (var entityType in entityTypes)
{
var tenantAtt = entityType.GetCustomAttribute<TenantAttribute>();//获取SqlSugar多租户特性
var ignoreInit = entityType.GetCustomAttribute<IgnoreInitTableAttribute>();//获取忽略初始化特性
if (ignoreInit != null) continue;//如果有忽略初始化特性
if (tenantAtt == null) continue;//如果没有租户特性就下一个
var db = DbContext.DB.GetConnectionScope(tenantAtt.configId.ToString());//获取数据库对象
var splitTable = entityType.GetCustomAttribute<SplitTableAttribute>();//获取自动分表特性
if (splitTable == null)//如果特性是空
db.CodeFirst.InitTables(entityType);//普通创建
else
db.CodeFirst.SplitTables().InitTables(entityType);//自动分表创建
}
}
/// <summary>
/// 初始化种子数据
/// </summary>
/// <param name="assemblyName">程序集名称</param>
private static void InitSeedData(string assemblyName)
{
// 获取所有种子配置-初始化数据
var seedDataTypes = App.EffectiveTypes.Where(u => !u.IsInterface && u is { IsAbstract: false, IsClass: true }
&& u.GetInterfaces().Any(i => i.HasImplementedRawGeneric(typeof(ISqlSugarEntitySeedData<>))) && u.Assembly.FullName == assemblyName);
if (!seedDataTypes.Any()) return;
foreach (var seedType in seedDataTypes)//遍历种子类
{
//使用与指定参数匹配程度最高的构造函数来创建指定类型的实例。
var instance = Activator.CreateInstance(seedType);
//获取SeedData方法
var hasDataMethod = seedType.GetMethod("SeedData");
//判断是否有种子数据
var seedData = ((IEnumerable)hasDataMethod?.Invoke(instance, null))?.Cast<object>();
if (seedData == null) continue;//没有种子数据就下一个
var entityType = seedType.GetInterfaces().First().GetGenericArguments().First();//获取实体类型
var tenantAtt = entityType.GetCustomAttribute<TenantAttribute>();//获取SqlSugar租户特性
if (tenantAtt == null) continue;//如果没有租户特性就下一个
var db = DbContext.DB.GetConnectionScope(tenantAtt.configId.ToString());//获取数据库对象
var config = DbContext.DB_CONFIGS.FirstOrDefault(u => u.ConfigId == tenantAtt.configId.ToString());//获取数据库配置
// var seedDataTable = seedData.ToList().ToDataTable();//获取种子数据:已弃用
var entityInfo = db.EntityMaintenance.GetEntityInfo(entityType);
// seedDataTable.TableName = db.EntityMaintenance.GetEntityInfo(entityType).DbTableName;//获取表名
var ignoreAdd = hasDataMethod.GetCustomAttribute<IgnoreSeedDataAddAttribute>();//读取忽略插入特性
var ignoreUpdate = hasDataMethod.GetCustomAttribute<IgnoreSeedDataUpdateAttribute>();//读取忽略更新特性
if (entityInfo.Columns.Any(u => u.IsPrimarykey))//判断种子数据是否有主键
{
// 按主键进行批量增加和更新
var storage = db.StorageableByObject(seedData.ToList()).ToStorage();
if (ignoreAdd == null) storage.AsInsertable.ExecuteCommand();//执行插入
if (ignoreUpdate == null) storage.AsUpdateable.ExecuteCommand();//只有没有忽略更新的特性才执行更新
}
else// 没有主键或者不是预定义的主键(有重复的可能)
{
//全量插入
// 无主键则只进行插入
if (!db.Queryable(entityInfo.DbTableName, entityInfo.DbTableName).Any() && ignoreAdd == null)
db.InsertableByObject(seedData.ToList()).ExecuteCommand();
}
}
}
/// <summary>
/// 判断类型是否实现某个泛型
/// </summary>
/// <param name="type">类型</param>
/// <param name="generic">泛型类型</param>
/// <returns>bool</returns>
public static bool HasImplementedRawGeneric(this Type type, Type generic)
{
// 检查接口类型
var isTheRawGenericType = type.GetInterfaces().Any(IsTheRawGenericType);
if (isTheRawGenericType) return true;
// 检查类型
while (type != null && type != typeof(object))
{
isTheRawGenericType = IsTheRawGenericType(type);
if (isTheRawGenericType) return true;
type = type.BaseType ?? default;
}
return false;
// 判断逻辑
bool IsTheRawGenericType(Type type) => generic == (type.IsGenericType ? type.GetGenericTypeDefinition() : type);
}
/// <summary>
/// List转DataTable
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <returns></returns>
public static DataTable ToDataTable<T>(this List<T> list)
{
var result = new DataTable();
if (list.Count > 0)
{
// result.TableName = list[0].GetType().Name; // 表名赋值
var propertys = list[0].GetType().GetProperties();
foreach (var pi in propertys)
{
var colType = pi.PropertyType;
if (colType.IsGenericType && colType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
colType = colType.GetGenericArguments()[0];
}
if (IsIgnoreColumn(pi))
continue;
if (IsJsonColumn(pi))//如果是json特性就是sting类型
colType = typeof(string);
result.Columns.Add(pi.Name, colType);
}
for (var i = 0; i < list.Count; i++)
{
var tempList = new ArrayList();
foreach (var pi in propertys)
{
if (IsIgnoreColumn(pi))
continue;
var obj = pi.GetValue(list[i], null);
if (IsJsonColumn(pi))//如果是json特性就是转化为json格式
obj = obj?.ToJson();//如果json字符串是空就传null
tempList.Add(obj);
}
var array = tempList.ToArray();
result.LoadDataRow(array, true);
}
}
return result;
}
/// <summary>
/// 排除SqlSugar忽略的列
/// </summary>
/// <param name="pi"></param>
/// <returns></returns>
private static bool IsIgnoreColumn(PropertyInfo pi)
{
var sc = pi.GetCustomAttributes<SugarColumn>(false).FirstOrDefault(u => u.IsIgnore);
return sc != null;
}
private static bool IsJsonColumn(PropertyInfo pi)
{
var sc = pi.GetCustomAttributes<SugarColumn>(false).FirstOrDefault(u => u.IsJson);
return sc != null;
}
}
@@ -0,0 +1,42 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// SqlSugar表信息
/// </summary>
public class SqlSugarTableInfo
{
/// <summary>
/// 所属库
///</summary>
public virtual string ConfigId { get; set; }
/// <summary>
/// 表名称
/// </summary>
public string TableName { get; set; }
/// <summary>
/// 实体名
/// </summary>
public string EntityName { get; set; }
/// <summary>
/// 表注释
/// </summary>
public string TableDescription { get; set; }
/// <summary>
/// 表字段
/// </summary>
public List<SqlSugarColumnInfo> Columns { get; set; }
}
@@ -0,0 +1,37 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// SqlSugar字段信息
/// </summary>
public class SqlSugarColumnInfo
{
/// <summary>
/// 字段名称
/// </summary>
public string ColumnName { get; set; }
/// <summary>
/// 是否主键
/// </summary>
public bool IsPrimaryKey { get; set; }
/// <summary>
/// 字段类型
/// </summary>
public string DataType { get; set; }
/// <summary>
/// 字段注释
/// </summary>
public string ColumnDescription { get; set; }
}
+154
View File
@@ -0,0 +1,154 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
using System.Text.RegularExpressions;
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// 种子数据工具类
/// </summary>
public class SeedDataUtil
{
public static List<T> GetSeedData<T>(string jsonName)
{
var seedData = new List<T>();//种子数据结果
var basePath = AppContext.BaseDirectory;//获取项目目录
var json = basePath.CombinePath("SeedData", "Json", jsonName);//获取文件路径
var dataString = FileHelper.ReadFile(json);//读取文件
if (!string.IsNullOrEmpty(dataString))//如果有内容
{
//字段没有数据的替换成null
dataString = dataString.Replace("\"\"", "null");
#region 针对导出的json字符串嵌套json字符串如 "DefaultDataScope": "{\"Level\":5,\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[]}"
//正则匹配"ConfigValue": "[{开头的字符串以]"结尾
var matcheDefaultDataScope = Regex.Matches(dataString, "\"DefaultDataScope\": \"\\{.*?\\}\"");
foreach (Match match in matcheDefaultDataScope)
{
//获取匹配的值
var value = match.Value;
//将匹配的值替换成"ConfigValue": "{XXX}"
//字符串是\"的替换成"
var newValue = value.Replace("\\\"", "\"");
//字符串是\{替换成{
newValue = newValue.Replace("\"{", "{");
//字符串是}"的替换成}
newValue = newValue.Replace("}\"", "}");
dataString = dataString.Replace(value, newValue);
}
#endregion 针对导出的json字符串嵌套json字符串如 "DefaultDataScope": "{\"Level\":5,\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[]}"
#region Sys_Org
//如果T是Sys_Org
var nameofT = typeof(T).Name;//获取类型名称
if (nameofT == "SysOrg")
{
//字段是"[的替换成[
dataString = dataString.Replace("\"[", "[");
//字段是]"的替换成]
dataString = dataString.Replace("]\"", "]");
}
#endregion
//将json字符串转为实体,这里ExtJson可以正常转换为字符串
var seedDataRecord1 = dataString.ToJsonEntity<SeedDataRecords<T>>();
//正则匹配"ConfigValue": "[{开头的字符串以]"结尾
var matches = Regex.Matches(dataString, "\"ConfigValue\": \"\\[\\{.*?\\}\\]\"");
foreach (Match match in matches)
{
//获取匹配的值
var value = match.Value;
//将匹配的值替换成"ConfigValue": "null"
dataString = dataString.Replace(value, "\"ConfigValue\": \"null\"");
}
#region 针对导出的json字符串嵌套json字符串如 "DefaultDataScope": "{\"Level\":5,\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[]}"
//字符串是\"的替换成"
dataString = dataString.Replace("\\\"", "\"");
//字符串是\{替换成{
dataString = dataString.Replace("\"{", "{");
//字符串是}"的替换成}
dataString = dataString.Replace("}\"", "}");
//将json字符串转为实体,这里ExtJson会转为null,替换字符串把ExtJson值变为实体类型而实体类是string类型
var seedDataRecord2 = dataString.ToJsonEntity<SeedDataRecords<T>>();
#endregion 针对导出的json字符串嵌套json字符串如 "DefaultDataScope": "{\"Level\":5,\"ScopeCategory\":\"SCOPE_ALL\",\"ScopeDefineOrgIdList\":[]}"
//遍历seedDataRecord2
for (var i = 0; i < seedDataRecord2.Records.Count; i++)
{
#region 处理ExtJosn
//获取ExtJson属性
var propertyExtJson = typeof(T).GetProperty(nameof(PrimaryKeyEntity.ExtJson));
if (propertyExtJson != null)
{
//获取ExtJson的值
var extJson = propertyExtJson.GetValue(seedDataRecord2.Records[i])?.ToString();
// 如果ExtJson不为空并且包含NullableDictionary表示序列化失败了
if (!string.IsNullOrEmpty(extJson) && extJson.Contains("NullableDictionary"))
{
//设置ExtJson为seedDataRecord1对应的值
extJson = propertyExtJson.GetValue(seedDataRecord1.Records[i])?.ToString();
//seedDataRecord2赋值seedDataRecord1的ExtJson
propertyExtJson.SetValue(seedDataRecord2.Records[i], extJson);
}
}
#endregion 处理ExtJosn
#region 处理ConfigValue
//获取ExtJson属性
var propertyConfigValue = typeof(T).GetProperty("ConfigValue");
if (propertyConfigValue != null)
{
//获取configValue的值
var configValue = propertyConfigValue.GetValue(seedDataRecord2.Records[i])?.ToString();
// 如果configValue不为空并且包含NullableDictionary表示序列化失败了
if (!string.IsNullOrEmpty(configValue) && (configValue.Contains("NullableDictionary") || configValue == "null"))
{
//设置ExtJson为seedDataRecord1对应的值
configValue = propertyConfigValue.GetValue(seedDataRecord1.Records[i])?.ToString();
//seedDataRecord2赋值seedDataRecord1的ExtJson
propertyConfigValue.SetValue(seedDataRecord2.Records[i], configValue);
}
}
#endregion 处理ConfigValue
}
//种子数据赋值
seedData = seedDataRecord2.Records;
}
return seedData;
}
}
/// <summary>
/// 种子数据格式实体类,遵循Navicat导出json格式
/// </summary>
/// <typeparam name="T"></typeparam>
public class SeedDataRecords<T>
{
/// <summary>
/// 数据
/// </summary>
public List<T> Records { get; set; }
}
+206
View File
@@ -0,0 +1,206 @@
// Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
//
// SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
// 1.请不要删除和修改根目录下的LICENSE文件。
// 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
// 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
// 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
// 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为。
// 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
namespace SimpleAdmin.SqlSugar;
/// <summary>
/// SqlSugar通用功能
/// </summary>
public static class SqlSugarUtils
{
/// <summary>
/// 根据特性获取所有表信息
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static List<SqlSugarTableInfo> GetTablesByAttribute<T>()
{
var tables = new List<SqlSugarTableInfo>();//结果集
// 获取实体表
var entityTypes = App.EffectiveTypes
.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsDefined(typeof(SugarTable), false))//有SugarTable特性
.Where(u => u.IsDefined(typeof(T), false));//具有指定特性
foreach (var entityType in entityTypes)
{
var tenantAttr = entityType.GetCustomAttribute<TenantAttribute>();//获取多租户特性
var configId = tenantAttr.configId.ToString();//获取租户Id
var connection = DbContext.DB.GetConnection(tenantAttr.configId.ToString());//根据租户ID获取连接信息
var entityInfo = connection.EntityMaintenance.GetEntityInfo(entityType);//获取实体信息
if (entityInfo != null)
{
var columns = GetTableColumns(configId, entityInfo.DbTableName);//获取字段信息
tables.Add(new SqlSugarTableInfo
{
TableName = entityInfo.DbTableName,
EntityName = entityInfo.EntityName,
TableDescription = entityInfo.TableDescription,
ConfigId = configId,
Columns = columns
});
}
}
return tables;
}
/// <summary>
/// 获取字段信息
/// </summary>
/// <param name="configId"></param>
/// <param name="tableName"></param>
/// <returns></returns>
public static List<SqlSugarColumnInfo> GetTableColumns(string configId, string tableName)
{
var columns = new List<SqlSugarColumnInfo>();//结果集
var connection = DbContext.DB.GetConnection(configId);
var dbColumnInfos = connection.DbMaintenance.GetColumnInfosByTableName(tableName);//根据表名获取表信息
if (dbColumnInfos != null)
{
//遍历字段获取信息
dbColumnInfos.ForEach(it =>
{
if (it.DbColumnName.Contains("_"))//如果有下划线,转换一下
{
var column = "";//新的字段值
var columnList = it.DbColumnName.Split('_');//根据下划线分割
columnList.ForEach(it =>
{
column += StringHelper.FirstCharToUpper(it);//首字母大写
});
it.DbColumnName = column;//赋值给数据库字段
}
else
{
it.DbColumnName = StringHelper.FirstCharToUpper(it.DbColumnName);//首字母大写
}
columns.Add(new SqlSugarColumnInfo
{
ColumnName = it.DbColumnName,
IsPrimaryKey = it.IsPrimarykey,
ColumnDescription = it.ColumnDescription,
DataType = it.DataType
});
});
}
return columns;
}
/// <summary>
/// 数据库字段类型转.NET类型
/// </summary>
/// <param name="dataType">字段类型</param>
/// <returns></returns>
public static string ConvertDataType(string dataType)
{
switch (dataType)
{
case "text":
case "varchar":
case "char":
case "nvarchar":
case "nchar":
case "blob":
case "longtext":
case "nclob":
return "string";
case "int":
case "mediumint":
return "int";
case "smallint":
return "Int16";
case "tinyint":
return "byte";
case "bigint":
case "integer"://sqlite数据库
return "long";
case "bit":
case "boolean":
return "bool";
case "money":
case "smallmoney":
case "numeric":
case "decimal":
return "decimal";
case "real":
return "Single";
case "datetime":
case "smalldatetime":
case "timestamp":
case "date":
case "year":
case "time":
return "DateTime";
case "float":
case "double":
return "double";
case "image":
case "binary":
case "varbinary":
return "byte[]";
case "uniqueidentifier":
return "Guid";
default:
return "string";
}
}
/// <summary>
/// 数据类型转显示类型
/// </summary>
/// <param name="dataType"></param>
/// <returns></returns>
public static string DataTypeToEff(string dataType)
{
return dataType switch
{
"string" => EffTypeConst.INPUT,
"int" => EffTypeConst.INPUT_NUMBER,
"long" => EffTypeConst.INPUT,
"float" => EffTypeConst.INPUT,
"double" => EffTypeConst.INPUT,
"decimal" => EffTypeConst.INPUT,
"bool" => EffTypeConst.SWITCH,
"Guid" => EffTypeConst.INPUT,
"DateTime" => EffTypeConst.DATEPICKER,
_ => EffTypeConst.INPUT
};
}
/// <summary>
/// 是否通用字段
/// </summary>
/// <param name="columnName">字段名</param>
/// <returns></returns>
public static bool IsCommonColumn(string columnName)
{
var columnList = new List<string>
{
nameof(BaseEntity.CreateTime), nameof(BaseEntity.UpdateTime),
nameof(BaseEntity.CreateUserId), nameof(BaseEntity.CreateUser),
nameof(BaseEntity.UpdateUserId), nameof(BaseEntity.UpdateUser),
nameof(BaseEntity.IsDelete), nameof(DataEntityBase.CreateOrgId),
nameof(PrimaryKeyEntity.ExtJson)
};
return columnList.Contains(columnName);
}
}