using SqlSugar;
using Mapster;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using System.Diagnostics;
using SqlSugar.Xugu;
namespace Data_logic
{
///
/// 业务逻辑基类
///
/// 与数据库中表的结构一致的模型类型
public class BaseDataLogic where T : class, new()
{
///
/// 主键个数
///
private int primarykeyCount = -1;
///
/// 主键属性信息
///
private PropertyInfo primarykeyInfo = null;
///
/// 构造函数
///
public BaseDataLogic()
{
//获取主键个数
if (primarykeyCount == -1)
{
var list = db.EntityMaintenance.GetEntityInfo().Columns.Where(d => d.IsPrimarykey == true);
primarykeyCount = list.Count();
primarykeyInfo = primarykeyCount == 1 ? list.FirstOrDefault().PropertyInfo : null;
}
//*
db.Aop.OnLogExecuting = (sql, pars) =>
{
Debugger.Log(1, "SQL", sql);
};
//*/
}
///
/// SqlSugar 操作对象,单例用SqlSugarClient,否则用SqlSugarClient
///
protected static SqlSugarScope db = new SqlSugarScope(new ConnectionConfig()
{
ConnectionString = "IP=10.1.1.1;DB=SYSTEM;User=SYSDBA;PWD=SYSDBA;Port=5138;AUTO_COMMIT=on;CHAR_SET=UTF8",//CHAR_SET=GBK
DbType = DbType.Custom.UseXugu(),
IsAutoCloseConnection = true,
//ConfigureExternalServices = new ConfigureExternalServices() { SqlFuncServices = SqlFuncCustom.Methods }
});
///
/// 从数据库中生成模型类文件
///
/// 文件放置的位置
/// 默认命名空间
/// 是否生成所有表。是则包含所有T开头的表,否则只生成当前对象名称相同的表
public void CreateModel(string path, string nameSpace = "Data.Model", bool allTable = false)
{
db.DbFirst.Where(c => allTable ? c.StartsWith("T") : typeof(T).Name == c)
.IsCreateAttribute().IsCreateDefaultValue()
.CreateClassFile(path, nameSpace);
}
///
/// 添加一条数据
///
/// 视图模型类型
/// 视图模型,仅包含模型中有的且值不为Null的字段
/// 是否添加成功,已存在视为false
public async Task Add(TModel model) where TModel : class
{
if (db.Queryable().In(primarykeyInfo.GetValue(model.Adapt())).Any()) return false;
return await db.Insertable(model)
.IgnoreColumns(ignoreNullColumn: true)
.ExecuteReturnBigIdentityAsync().ContinueWith(t =>
t.Result>0
);
}
///
/// 根据主键或根据条件更新数据
///
/// 视图模型类型
/// 视图模型,仅包含模型中有的且值不为Null的字段
/// 查询条件,当条件为Null时为主键更新(T必须配置主键),否则为条件批量更新
/// 更新是否成功,不存在视为false
/// 类型T未配置主键或有多个主键
public async Task Update(TModel model, Expression> where = null) where TModel : class
{
if (where != null && this.primarykeyCount != 1) throw new Exception($"类型'{typeof(T).Name}'未配置主键或有多个主键");
var expression = db.Updateable(model);
if (where != null) expression = expression.Where(where);
return await expression
.IgnoreColumns(ignoreAllNullColumns: true)
.ExecuteCommandHasChangeAsync();
}
///
/// 根据主键插入或更新一条数据
///
/// 视图模型类型(必须配置主键)
/// 视图模型,仅包含模型中有的且值不为Null的字段
/// 更新是否成功
/// 类型T未配置主键或有多个主键
public async Task AddOrUpdate(TModel model) where TModel : class, new()
{
if (this.primarykeyCount != 1) throw new Exception($"类型'{typeof(T).Name}'未配置主键或有多个主键");
if (!await db.Queryable().In(primarykeyInfo.GetValue(model.Adapt())).AnyAsync()) return await Add(model);
else return await Update(model);
/*
var o = db.Storageable(model.Adapt()).ToStorage();
o.AsInsertable.ExecuteCommand();//不存在插入
o.AsUpdateable.ExecuteCommand();//存在更新
return await db.Storageable(model.Adapt())
.ExecuteCommandAsync()
.ContinueWith(t => t.Result > 0);
*/
}
///
/// 根据主键删除数据
///
/// 主键的类型
/// 主键值
/// 删除是否成功
/// 类型T未配置主键或有多个主键
public async Task Delete(TKey id)
{
if (this.primarykeyCount != 1) throw new Exception($"类型'{typeof(T).Name}'未配置主键或有多个主键");
//不存在时视为删除成功
if (!await db.Queryable().In(id).AnyAsync()) return true;
return await db.Deleteable(id).ExecuteCommandHasChangeAsync();
}
///
/// 根据查询条件删除数据
///
/// 查询条件表达式
/// 删除是否成功
public async Task Delete(Expression> where)
{
//不存在时视为删除成功
if (!await db.Queryable().Where(where).AnyAsync()) return true;
return await db.Deleteable(where).ExecuteCommandHasChangeAsync();
}
///
/// 根据单个主键获取一条数据
///
/// 要返回的模型类型
/// 主键的类型
/// 主键值
/// 返回指定主键值的数据
/// 类型T未配置主键或有多个主键
public async Task Single(TKey id)
{
if (this.primarykeyCount != 1) throw new Exception($"类型'{typeof(T).Name}'未配置主键或有多个主键");
return await db.Queryable().InSingleAsync(id).ContinueWith(t => t.Result.Adapt());
}
///
/// 根据条件获取唯一数据
///
/// 要返回的模型类型
/// 主键的类型
/// 查询条件
/// 返回符合指定条件的唯一数据,不唯一时将抛出异常
public async Task Single(Expression> where)
{
return await db.Queryable().Where(where).Select().SingleAsync();
}
///
/// 获取符合条件的分页数据
///
/// 列表模型的类型
/// 条件表达式
/// 排序表达式
/// 排序方向,默认顺序
/// 页码,从1开始
/// 每页条数,默认20
/// 符合条件的分页数据列表,以及总条数
public async Task<(List, int)> List(Expression> where = null
, Expression> order = null, OrderByType orderType = OrderByType.Asc
, int pageNum = 1, int pageSize = 20, bool noPager = false)
{
var expression = db.Queryable();
if (where != null && where.ToString() != "it => True") expression = expression.Where(where);
if (order != null) expression = expression.OrderBy(order, orderType);
var expressionTModel = expression.Select();
if (noPager) return await expressionTModel.ToListAsync().ContinueWith(d => (d.Result, d.Result.Count));
else return await ToPagedList(expressionTModel, pageNum, pageSize);
}
///
/// 通用分页
///
/// 列表模型的类型
/// 查询表达式
/// 页码,从1开始
/// 每页条数,默认20
/// 返回查询表达式分页后的数据列表,以及总条数
protected static async Task<(List, int)> ToPagedList(ISugarQueryable expression, int pageNum = 1, int pageSize = 20)
{
RefAsync totalCount = 0;
return await expression
.ToPageListAsync/*ToOffsetPageAsync//2012以上才支持*/(pageNum, pageSize, totalCount)
.ContinueWith(d => (d.Result, totalCount));
}
///
/// 获取动态where条件对象
///
/// 动态where条件对象
public Expressionable CreateWhere() => Expressionable.Create();
}
}