/////////////////////////////////////////////////////////////////////////////////
// 宁波拓通e智造平台 ToTong Next Builder //
// https://git.tuotong-tech.com/tnb/tnb.server //
/////////////////////////////////////////////////////////////////////////////////
using System.Collections.Concurrent;
using JNPF;
using JNPF.DependencyInjection;
using Mapster;
using SqlSugar;
using Tnb.VmodelEngine;
namespace Tnb.DataAccess;
///
///
///
public class DataAccess : IDataAccess, ITransient, IDisposable
{
const int MAX_PAGE_SIZE = 1000;
private ISqlSugarClient? sugar;
protected ISqlSugarClient Db
{
get
{
if (sugar == null)
{
ConnectionStringsOptions conn = App.GetConfig("ConnectionStrings", true);
//var DBType = (DbType)Enum.Parse(typeof(DbType), conn.DBType);
sugar = new SqlSugarScope(new ConnectionConfig
{
ConnectionString = conn.ConnectString,
DbType = conn.DBType.Adapt(),
IsAutoCloseConnection = true,
ConfigId = conn.ConfigId,
InitKeyType = InitKeyType.Attribute,
MoreSettings = new ConnMoreSettings()
{
IsAutoRemoveDataCache = true, // 自动清理缓存
IsAutoToUpper = false,
PgSqlIsAutoToLower = false,
DisableNvarchar = true
},
}, SugarHelper.ConfigSugar);
}
return sugar;
}
}
///
/// 全局缓存
///
static ConcurrentDictionary DbCache = new ConcurrentDictionary();
///
/// 构造
///
public DataAccess()
{
}
///
/// 释放
///
public void Dispose()
{
foreach (var item in DbCache)
{
item.Value.Dispose();
}
DbCache.Clear();
}
///
/// 获取 ISqlSugarClient
///
public ISqlSugarClient GetSqlSugar(string? dbCode = null)
{
if (string.IsNullOrEmpty(dbCode) || dbCode == DbConsts.DefaultDbCode)
{
return Db;
}
if (DbCache.ContainsKey(dbCode))
{
return DbCache[dbCode];
}
var dblink = GetVmLink(dbCode);
if (dblink == null)
{
throw new Exception($"没有此数据库{dbCode}连接信息");
}
var dbType = Enum.Parse(dblink.dbType.ToString(), true);
var sugar = new SqlSugarScope(new ConnectionConfig
{
ConnectionString = dblink.dbConnection,
DbType = dbType,
IsAutoCloseConnection = true,
ConfigId = dblink.dbCode,
InitKeyType = InitKeyType.Attribute,
MoreSettings = new ConnMoreSettings()
{
IsAutoRemoveDataCache = true, // 自动清理缓存
IsAutoToUpper = false,
PgSqlIsAutoToLower = false,
DisableNvarchar = true
},
}, SugarHelper.ConfigSugar);
if (sugar.Ado.IsValidConnection())
{
DbCache[dbCode] = sugar;
}
else
{
sugar.Dispose();
throw new Exception($"无法连接到数据库{dbCode}");
}
return DbCache[dbCode];
}
///
/// 获取 DbLink
///
public VmodelLink GetVmLink(string dbCode)
{
var model = Db.Queryable().First(a => a.dbCode == dbCode);
return model;
}
///
/// 获取 Vmodel, 为空时不抛异常
///
public async Task TryGetVmodelAsync(string id, bool loadNavigate = false)
{
Vmodel vm = await Db.Queryable().FirstAsync(a => a.id == id && a.deleted == 0);
if (vm != null && loadNavigate)
{
await LoadVmodelNavigateAsync(vm);
}
return vm;
}
///
/// 获取 Vmodel, 为空时抛异常
///
public async Task GetVmodelAsync(string id, bool loadNavigate = false)
{
Vmodel vm = await Db.Queryable().FirstAsync(a => a.id == id && a.deleted == 0);
ArgumentNullException.ThrowIfNull(vm, $"找不到vmid={id}的模型");
if (loadNavigate)
{
await LoadVmodelNavigateAsync(vm);
}
return vm;
}
///
/// 获取 Vmodel, 为空时不抛异常
///
public async Task TryGetVmodelAsync(string area, string vmCode, bool loadNavigate = false)
{
Vmodel vm = await Db.Queryable().FirstAsync(a => a.area == area && a.vmCode == vmCode && a.deleted == 0);
if (vm != null && loadNavigate)
{
await LoadVmodelNavigateAsync(vm);
}
return vm;
}
///
/// 获取 Vmodel, 为空时抛异常
///
public async Task GetVmodelAsync(string area, string vmCode, bool loadNavigate = false)
{
Vmodel vm = await Db.Queryable().FirstAsync(a => a.area == area && a.vmCode == vmCode && a.deleted == 0);
ArgumentNullException.ThrowIfNull(vm, $"找不到area={area}, vmCode={vmCode}的模型");
if (loadNavigate)
{
await LoadVmodelNavigateAsync(vm);
}
return vm;
}
/////
///// 获取 Vmodel
/////
//public async Task GetVmodelAsync(string tableName, string? dbCode)
//{
// Vmodel vm = await _db.Queryable().FirstAsync(a => a.tableName == tableName && a.dbCode == dbCode && a.deleted == 0);
// return vm;
//}
///
/// 加载模型的导航属性
///
///
///
private async Task LoadVmodelNavigateAsync(Vmodel vm)
{
Dictionary dictVm = new();
foreach (var navProp in vm.navProps)
{
if (!dictVm.ContainsKey(navProp.vmid))
{
var navModel = await GetVmodelAsync(navProp.vmid);
dictVm.Add(navProp.vmid, navModel);
}
navProp.naviModel = dictVm[navProp.vmid];
}
}
///
/// 查询数据 默认方法
///
public async Task QueryDataAsync(Vmodel vm, VmQueryInput input)
{
ISqlSugarClient db = GetSqlSugar(vm.dbCode);
var query = db.Queryable