using System; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Dynamic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SqlSugar { public partial class SqlSugarClient : ISqlSugarClient, ITenant { #region Gobal Property private SqlSugarProvider _Context = null; private string _ThreadId; private ConnectionConfig _CurrentConnectionConfig; internal List _AllClients; private bool _IsAllTran = false; private bool _IsOpen = false; private MappingTableList _MappingTables; private MappingColumnList _MappingColumns; private IgnoreColumnList _IgnoreColumns; private IgnoreColumnList _IgnoreInsertColumns; internal Guid? AsyncId { get; set; } internal bool? IsSingleInstance { get; set; } #endregion #region Constructor public SqlSugarClient(ConnectionConfig config) { Check.Exception(config == null, "ConnectionConfig config is null"); InitContext(config); } public SqlSugarClient(List configs) { Check.Exception(configs.IsNullOrEmpty(), "List configs is null or count=0"); InitConfigs(configs); var config = configs.First(); InitContext(config); _AllClients = configs.Select(it => new SugarTenant() { ConnectionConfig = it }).ToList(); ; _AllClients.First(it => it.ConnectionConfig.ConfigId == config.ConfigId).Context = this.Context; } public SqlSugarClient(ConnectionConfig config ,Action configAction) { Check.Exception(config == null, "ConnectionConfig config is null"); InitContext(config); configAction(this); } public SqlSugarClient(List configs, Action configAction) { Check.Exception(configs.IsNullOrEmpty(), "List configs is null or count=0"); InitConfigs(configs); var config = configs.First(); InitContext(config); _AllClients = configs.Select(it => new SugarTenant() { ConnectionConfig = it }).ToList(); ; _AllClients.First(it => it.ConnectionConfig.ConfigId == config.ConfigId).Context = this.Context; configAction(this); } #endregion #region Global variable public SugarActionType SugarActionType { get { return this.Context.SugarActionType; }set { this.Context.SugarActionType = value; } } public SqlSugarProvider Context { get { return GetContext(); } } public bool IsSystemTablesConfig => this.Context.IsSystemTablesConfig; public ConnectionConfig CurrentConnectionConfig { get { return _CurrentConnectionConfig; } set { _CurrentConnectionConfig = value; } } public Guid ContextID { get { return this.Context.ContextID; } set { this.Context.ContextID = value; } } public ConfigQuery ConfigQuery { get { return this.Context.ConfigQuery; } set { this.Context.ConfigQuery = value; } } public MappingTableList MappingTables { get { return _MappingTables; } set { _MappingTables = value; } } public MappingColumnList MappingColumns { get { return _MappingColumns; } set { _MappingColumns = value; } } public IgnoreColumnList IgnoreColumns { get { return _IgnoreColumns; } set { _IgnoreColumns = value; } } public IgnoreColumnList IgnoreInsertColumns { get { return _IgnoreInsertColumns; } set { _IgnoreInsertColumns = value; } } public Dictionary TempItems { get { return this.Context.TempItems; } set { this.Context.TempItems = value; } } #endregion #region SimpleClient public T CreateContext(bool isTran=true) where T : SugarUnitOfWork, new() { T result = new T(); _CreateContext(isTran, result); var type = typeof(T); var ps = type.GetProperties(); var cacheKey = "SugarUnitOfWork" + typeof(T).FullName + typeof(T).GetHashCode(); var properies = new ReflectionInoCacheService().GetOrCreate(cacheKey, () => ps.Where(it => (it.PropertyType.BaseType != null && it.PropertyType.BaseType.Name.StartsWith("SimpleClient`")) || it.PropertyType.Name.StartsWith("SimpleClient`") )); foreach (var item in properies) { var value = Activator.CreateInstance(item.PropertyType); TenantAttribute tenantAttribute = item.PropertyType.GetGenericArguments()[0].GetCustomAttribute(); if (tenantAttribute == null) { value.GetType().GetProperty("Context").SetValue(value, this); } else { value.GetType().GetProperty("Context").SetValue(value, this.GetConnection(tenantAttribute.configId)); } item.SetValue(result, value); } return result; } public SugarUnitOfWork CreateContext(bool isTran = true) { SugarUnitOfWork sugarUnitOf = new SugarUnitOfWork(); return _CreateContext(isTran, sugarUnitOf); } private SugarUnitOfWork _CreateContext(bool isTran, SugarUnitOfWork sugarUnitOf) { sugarUnitOf.Db = this; sugarUnitOf.Tenant = this; sugarUnitOf.IsTran = isTran; this.Open(); if (isTran) this.BeginTran(); return sugarUnitOf; } public SimpleClient GetSimpleClient() where T : class, new() { return this.Context.GetSimpleClient(); } public RepositoryType GetRepository() where RepositoryType : ISugarRepository , new() { Type type = typeof(RepositoryType); var isAnyParamter = type.GetConstructors().Any(z => z.GetParameters().Any()); object o = null; if (isAnyParamter) { o = Activator.CreateInstance(type, new string[] { null }); } else { o = Activator.CreateInstance(type); } var result = (RepositoryType)o; if (result.Context == null) { result.Context = this.Context; } return result; } #endregion #region Insertable public IInsertable> InsertableByDynamic(object insertDynamicObject) { return this.Context.InsertableByDynamic(insertDynamicObject); } public InsertMethodInfo InsertableByObject(object singleEntityObjectOrListObject) { return this.Context.InsertableByObject(singleEntityObjectOrListObject); } public IInsertable Insertable(Dictionary columnDictionary) where T : class, new() { return this.Context.Insertable(columnDictionary); } public IInsertable Insertable(dynamic insertDynamicObject) where T : class, new() { if (insertDynamicObject is IList) { return this.Context.Insertable((insertDynamicObject as IList).ToList()); } return this.Context.Insertable(insertDynamicObject); } public IInsertable Insertable(List insertObjs) where T : class, new() { return this.Context.Insertable(insertObjs); } public IInsertable Insertable(T insertObj) where T : class, new() { Check.ExceptionEasy(typeof(T).FullName.Contains("System.Collections.Generic.List`"), " need where T: class, new() ","需要Class,new()约束,并且类属性中不能有required修饰符"); if (typeof(T).Name == "Object") { Check.ExceptionEasy("Object type use db.InsertableByObject(obj).ExecuteCommand()", "检测到T为Object类型,请使用 db.InsertableByObject(obj).ExecuteCommand(),Insertable不支持object,InsertableByObject可以(缺点:功能比较少)"); } return this.Context.Insertable(insertObj); } public IInsertable Insertable(T[] insertObjs) where T : class, new() { return this.Context.Insertable(insertObjs); } #endregion #region Queryable #region Nav CUD public InsertNavTaskInit InsertNav(T data) where T : class, new() { return this.Context.InsertNav(data); } public InsertNavTaskInit InsertNav(List datas) where T : class, new() { return this.Context.InsertNav(datas); } public InsertNavTaskInit InsertNav(T data, InsertNavRootOptions rootOptions) where T : class, new() { return this.Context.InsertNav(data, rootOptions); } public InsertNavTaskInit InsertNav(List datas, InsertNavRootOptions rootOptions) where T : class, new() { return this.Context.InsertNav(datas, rootOptions); } public DeleteNavTaskInit DeleteNav(T data) where T : class, new() { return this.Context.DeleteNav(data); } public DeleteNavTaskInit DeleteNav(List datas) where T : class, new() { return this.Context.DeleteNav(datas); } public DeleteNavTaskInit DeleteNav(Expression> whereExpression) where T : class, new() { return this.Context.DeleteNav(whereExpression); } public DeleteNavTaskInit DeleteNav(T data, DeleteNavRootOptions options) where T : class, new() { return this.Context.DeleteNav(data, options); } public DeleteNavTaskInit DeleteNav(List datas, DeleteNavRootOptions options) where T : class, new() { return this.Context.DeleteNav(datas, options); } public DeleteNavTaskInit DeleteNav(Expression> whereExpression, DeleteNavRootOptions options) where T : class, new() { return this.Context.DeleteNav(whereExpression, options); } public UpdateNavTaskInit UpdateNav(T data) where T : class, new() { return this.Context.UpdateNav(data); } public UpdateNavTaskInit UpdateNav(List datas,UpdateNavRootOptions rootOptions) where T : class, new() { return this.Context.UpdateNav(datas, rootOptions); } public UpdateNavTaskInit UpdateNav(T data, UpdateNavRootOptions rootOptions) where T : class, new() { return this.Context.UpdateNav(data,rootOptions); } public UpdateNavTaskInit UpdateNav(List datas) where T : class, new() { return this.Context.UpdateNav(datas); } #endregion #region Union public ISugarQueryable Union(List> queryables) where T : class, new() { return this.Context.Union(queryables); } public ISugarQueryable Union(params ISugarQueryable[] queryables) where T : class, new() { return this.Context.Union(queryables); } public ISugarQueryable UnionAll(List> queryables) where T : class, new() { return this.Context.UnionAll(queryables); } public ISugarQueryable UnionAll(params ISugarQueryable[] queryables) where T : class, new() { return this.Context.UnionAll(queryables); } #endregion public QueryMethodInfo QueryableByObject(Type entityType) { return this.Context.QueryableByObject(entityType); } public QueryMethodInfo QueryableByObject(Type entityType,string shortName) { return this.Context.QueryableByObject(entityType,shortName); } public ISugarQueryable MasterQueryable() { return this.Context.MasterQueryable(); } public ISugarQueryable SlaveQueryable() { return this.Context.SlaveQueryable(); } public ISugarQueryable SqlQueryable(string sql) where T : class, new() { return this.Context.SqlQueryable(sql); } public ISugarQueryable Queryable(string tableName, string shortName) { return this.Context.Queryable(tableName, shortName); } public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) where T : class, new() { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(Expression> joinExpression) { return this.Context.Queryable(joinExpression); } public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, Expression> joinExpression) where T : class, new() where T2 : class, new() { return this.Context.Queryable(joinQueryable1, joinQueryable2, joinExpression).With(SqlWith.Null); } public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, JoinType joinType, Expression> joinExpression) where T : class, new() where T2 : class, new() { return this.Context.Queryable(joinQueryable1, joinQueryable2, joinType, joinExpression).With(SqlWith.Null); } public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, ISugarQueryable joinQueryable3, JoinType joinType1, Expression> joinExpression1, JoinType joinType2, Expression> joinExpression2) where T : class, new() where T2 : class, new() where T3 : class, new() { return this.Context.Queryable(joinQueryable1, joinQueryable2, joinQueryable3, joinType1, joinExpression1, joinType2, joinExpression2).With(SqlWith.Null); } public ISugarQueryable Queryable(ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, ISugarQueryable joinQueryable3, ISugarQueryable joinQueryable4, JoinType joinType1, Expression> joinExpression1, JoinType joinType2, Expression> joinExpression2, JoinType joinType3, Expression> joinExpression3) where T : class, new() where T2 : class, new() where T3 : class, new() where T4 : class ,new () { return this.Context.Queryable(joinQueryable1, joinQueryable2, joinQueryable3, joinQueryable4, joinType1, joinExpression1, joinType2, joinExpression2,joinType3, joinExpression3).With(SqlWith.Null); } public ISugarQueryable Queryable() { return this.Context.Queryable(); } public ISugarQueryable Queryable(ISugarQueryable queryable) { var result= this.Context.Queryable(queryable); var QueryBuilder = queryable.QueryBuilder; result.QueryBuilder.IsQueryInQuery = true; var appendIndex = result.QueryBuilder.Parameters==null?1:result.QueryBuilder.Parameters.Count+1; result.QueryBuilder.WhereIndex = (QueryBuilder.WhereIndex+1); result.QueryBuilder.LambdaExpressions.ParameterIndex = (QueryBuilder.LambdaExpressions.ParameterIndex+ appendIndex); return result; } public ISugarQueryable Queryable(ISugarQueryable queryable,string shortName) { return this.Context.Queryable(queryable,shortName); } public ISugarQueryable Queryable(string shortName) { return this.Context.Queryable(shortName); } #endregion #region Saveable public GridSaveProvider GridSave(List saveList) where T : class, new() { return this.Context.GridSave(saveList); } public GridSaveProvider GridSave(List oldList, List saveList) where T : class, new() { return this.Context.GridSave(oldList, saveList); } public StorageableDataTable Storageable(DataTable data) { return this.Context.Storageable(data); } public StorageableDataTable Storageable(List> dictionaryList,string tableName) { DataTable dt = this.Context.Utilities.DictionaryListToDataTable(dictionaryList); dt.TableName = tableName; return this.Context.Storageable(dt); } public StorageableDataTable Storageable(Dictionary dictionary, string tableName) { DataTable dt = this.Context.Utilities.DictionaryListToDataTable(new List>() { dictionary }); dt.TableName = tableName; return this.Context.Storageable(dt); } public IStorageable Storageable(List dataList) where T : class, new() { return this.Context.Storageable(dataList); } public IStorageable Storageable(IList dataList) where T : class, new() { return this.Context.Storageable(dataList.ToList()); } public IStorageable Storageable(T[] dataList) where T : class, new() { return this.Context.Storageable(dataList?.ToList()); } public IStorageable Storageable(T data) where T : class, new() { Check.Exception(typeof(T).FullName.Contains("System.Collections.Generic.List`"), " need where T: class, new() "); return this.Context.Storageable(new List { data}); } [Obsolete("use Storageable")] public ISaveable Saveable(List saveObjects) where T : class, new() { return this.Context.Saveable(saveObjects); } [Obsolete("use Storageable")] public ISaveable Saveable(T saveObject) where T : class, new() { return this.Context.Saveable(saveObject); } public StorageableMethodInfo StorageableByObject(object singleEntityObjectOrListObject) { return this.Context.StorageableByObject(singleEntityObjectOrListObject); } #endregion #region Reportable public IReportable Reportable(T data) { return this.Context.Reportable(data); } public IReportable Reportable(List list) { return this.Context.Reportable(list); } public IReportable Reportable(T [] array) { return this.Context.Reportable(array); } #endregion #region Queue public QueueList Queues { get { return this.Context.Queues; } set { this.Context.Queues = value; } } public void AddQueue(string sql, object parsmeters = null) { this.Context.AddQueue(sql, parsmeters); } public void AddQueue(string sql, List parsmeters) { this.Context.AddQueue(sql, parsmeters); } public void AddQueue(string sql, SugarParameter parsmeter) { this.Context.AddQueue(sql, parsmeter); } public int SaveQueues(bool isTran = true) { return this.Context.SaveQueues(isTran); } public Tuple, List, List, List, List, List, List> SaveQueues(bool isTran = true) { return this.Context.SaveQueues(isTran); } public Tuple, List, List, List, List, List> SaveQueues(bool isTran = true) { return this.Context.SaveQueues(isTran); } public Tuple, List, List, List, List> SaveQueues(bool isTran = true) { return this.Context.SaveQueues(isTran); } public Tuple, List, List, List> SaveQueues(bool isTran = true) { return this.Context.SaveQueues(isTran); } public Tuple, List, List> SaveQueues(bool isTran = true) { return this.Context.SaveQueues(isTran); } public Tuple, List> SaveQueues(bool isTran = true) { return this.Context.SaveQueues(isTran); } public List SaveQueues(bool isTran = true) { return this.Context.SaveQueues(isTran); } public Task SaveQueuesAsync(bool isTran = true) { return this.Context.SaveQueuesAsync(isTran); } public Task, List, List, List, List, List, List>> SaveQueuesAsync(bool isTran = true) { return this.Context.SaveQueuesAsync(isTran); } public Task, List, List, List, List, List>> SaveQueuesAsync(bool isTran = true) { return this.Context.SaveQueuesAsync(isTran); } public Task, List, List, List, List>> SaveQueuesAsync(bool isTran = true) { return this.Context.SaveQueuesAsync(isTran); } public Task, List, List, List>> SaveQueuesAsync(bool isTran = true) { return this.Context.SaveQueuesAsync(isTran); } public Task, List, List>> SaveQueuesAsync(bool isTran = true) { return this.Context.SaveQueuesAsync(isTran); } public Task, List>> SaveQueuesAsync(bool isTran = true) { return this.Context.SaveQueuesAsync(isTran); } public Task> SaveQueuesAsync(bool isTran = true) { return this.Context.SaveQueuesAsync(isTran); } #endregion #region Updateable public IUpdateable> UpdateableByDynamic(object updateDynamicObject) { return this.Context.UpdateableByDynamic(updateDynamicObject); } public UpdateMethodInfo UpdateableByObject(object singleEntityObjectOrListObject) { return this.Context.UpdateableByObject(singleEntityObjectOrListObject); } public UpdateExpressionMethodInfo UpdateableByObject(Type entityType) { return this.Context.UpdateableByObject(entityType); } public IUpdateable Updateable() where T : class, new() { return this.Context.Updateable(); } public IUpdateable Updateable(Dictionary columnDictionary) where T : class, new() { return this.Context.Updateable(columnDictionary); } public IUpdateable Updateable(dynamic updateDynamicObject) where T : class, new() { if (updateDynamicObject is IList) { return this.Context.Updateable((updateDynamicObject as IList).ToList()); } return this.Context.Updateable(updateDynamicObject); } public IUpdateable Updateable(Expression> columns) where T : class, new() { return this.Context.Updateable(columns); } public IUpdateable Updateable(Expression> columns) where T : class, new() { return this.Context.Updateable(columns); } public IUpdateable Updateable(List UpdateObjs) where T : class, new() { return this.Context.Updateable(UpdateObjs); } public IUpdateable Updateable(T UpdateObj) where T : class, new() { return this.Context.Updateable(UpdateObj); } public IUpdateable Updateable(T[] UpdateObjs) where T : class, new() { return this.Context.Updateable(UpdateObjs); } #endregion #region Ado public IAdo Ado => this.Context.Ado; #endregion #region Deleteable public DeleteMethodInfo DeleteableByObject(object singleEntityObjectOrListObject) { return this.Context.DeleteableByObject(singleEntityObjectOrListObject); } public IDeleteable Deleteable() where T : class, new() { return this.Context.Deleteable(); } public IDeleteable Deleteable(dynamic primaryKeyValue) where T : class, new() { return this.Context.Deleteable(primaryKeyValue); } public IDeleteable Deleteable(dynamic[] primaryKeyValues) where T : class, new() { return this.Context.Deleteable(primaryKeyValues); } public IDeleteable Deleteable(Expression> expression) where T : class, new() { return this.Context.Deleteable(expression); } public IDeleteable Deleteable(List pkValue) where T : class, new() { return this.Context.Deleteable(pkValue); } public IDeleteable Deleteable(List deleteObjs) where T : class, new() { return this.Context.Deleteable(deleteObjs); } public IDeleteable Deleteable(T deleteObj) where T : class, new() { return this.Context.Deleteable(deleteObj); } #endregion #region Fastest public IFastest Fastest() where T : class, new() { return this.Context.Fastest(); } #endregion #region ThenMapper public void ThenMapper(IEnumerable list, Action action) { this.Context.ThenMapper(list, action); } public Task ThenMapperAsync(IEnumerable list, Func action) { return this.Context.ThenMapperAsync(list,action); } #endregion #region More api public IContextMethods Utilities { get { return this.Context.Utilities; } set { this.Context.Utilities = value; } } public AopProvider Aop => this.Context.Aop; public ICodeFirst CodeFirst => this.Context.CodeFirst; public IDbFirst DbFirst => this.Context.DbFirst; public IDbMaintenance DbMaintenance => this.Context.DbMaintenance; public EntityMaintenance EntityMaintenance { get { return this.Context.EntityMaintenance; } set { this.Context.EntityMaintenance = value; } } public QueryFilterProvider QueryFilter { get { return this.Context.QueryFilter; } set { this.Context.QueryFilter = value; } } #endregion #region TenantManager public ITenant AsTenant() { var tenant= this as ITenant; return tenant; } public SqlSugarTransaction UseTran() { return new SqlSugarTransaction(this); } public void RemoveConnection(dynamic configId) { var removeData= this._AllClients.FirstOrDefault(it => ((object)it.ConnectionConfig.ConfigId).ObjToString()== ((object)configId).ObjToString()); object currentId= this.CurrentConnectionConfig.ConfigId; if (removeData != null) { if (removeData.Context.Ado.IsAnyTran()) { Check.ExceptionEasy("RemoveConnection error has tran",$"删除失败{removeData.ConnectionConfig.ConfigId}存在未提交事务"); } else if (((object)removeData.ConnectionConfig.ConfigId).ObjToString()== currentId.ObjToString()) { Check.ExceptionEasy("Default ConfigId cannot be deleted", $"默认库不能删除{removeData.ConnectionConfig.ConfigId}"); } this._AllClients.Remove(removeData); } } public void AddConnection(ConnectionConfig connection) { Check.ArgumentNullException(connection, "AddConnection.connection can't be null"); InitTenant(); var db = this._AllClients.FirstOrDefault(it => ((object)it.ConnectionConfig.ConfigId).ObjToString() == ((object)connection.ConfigId).ObjToString()); if (db == null) { if (this._AllClients == null) { this._AllClients = new List(); } var provider = new SqlSugarProvider(connection); if (connection.AopEvents != null) { provider.Ado.IsEnableLogEvent = true; } this._AllClients.Add(new SugarTenant() { ConnectionConfig = connection, Context = provider }); } } public SqlSugarProvider GetConnectionWithAttr() { var attr = typeof(T).GetCustomAttribute(); if (attr == null) return this.GetConnection(this.CurrentConnectionConfig.ConfigId); var configId = attr.configId; return this.GetConnection(configId); } public SqlSugarProvider GetConnectionWithAttr(Type type) { var attr = type.GetCustomAttribute(); if (attr == null) return this.GetConnection(this.CurrentConnectionConfig.ConfigId); var configId = attr.configId; return this.GetConnection(configId); } public SqlSugarScopeProvider GetConnectionScopeWithAttr() { var attr = typeof(T).GetCustomAttribute(); if (attr == null) return this.GetConnectionScope(this.CurrentConnectionConfig.ConfigId); var configId = attr.configId; return this.GetConnectionScope(configId); } public SqlSugarProvider GetConnection(object configId) { InitTenant(); var db = this._AllClients.FirstOrDefault(it =>Convert.ToString(it.ConnectionConfig.ConfigId) ==Convert.ToString(configId)); if (db == null) { Check.Exception(true, "ConfigId was not found {0}", configId+""); } if (db.Context == null) { db.Context = new SqlSugarProvider(db.ConnectionConfig); } var intiAop=db.Context.Aop; if (db.Context.CurrentConnectionConfig.AopEvents == null) { db.Context.CurrentConnectionConfig.AopEvents = new AopEvents(); } if (_IsAllTran && db.Context.Ado.Transaction == null) { db.Context.Ado.BeginTran(); } db.Context.Root = this; if (db.Context.MappingTables == null) { db.Context.MappingTables = new MappingTableList(); } return db.Context; } public SqlSugarScopeProvider GetConnectionScope(object configId) { var conn = GetConnection(configId); return new SqlSugarScopeProvider(conn); } public bool IsAnyConnection(object configId) { InitTenant(); var db = this._AllClients.FirstOrDefault(it => Convert.ToString(it.ConnectionConfig.ConfigId) == Convert.ToString(configId)); return db != null; } public void ChangeDatabase(object configId) { configId =Convert.ToString(configId); var isLog = _Context.Ado.IsEnableLogEvent; Check.Exception(!_AllClients.Any(it =>Convert.ToString( it.ConnectionConfig.ConfigId) ==Convert.ToString( configId)), "ConfigId was not found {0}", configId+""); InitTenant(_AllClients.First(it => Convert.ToString(it.ConnectionConfig.ConfigId )==Convert.ToString( configId))); if (this._IsAllTran) this.Ado.BeginTran(); if (this._IsOpen) this.Open(); _Context.Ado.IsEnableLogEvent = isLog; if (_CurrentConnectionConfig.AopEvents==null) _CurrentConnectionConfig.AopEvents = new AopEvents(); } public void ChangeDatabase(Func changeExpression) { var isLog = _Context.Ado.IsEnableLogEvent; var allConfigs = _AllClients.Select(it => it.ConnectionConfig); Check.Exception(!allConfigs.Any(changeExpression), "changeExpression was not found {0}", changeExpression.ToString()); InitTenant(_AllClients.First(it => it.ConnectionConfig == allConfigs.First(changeExpression))); if (this._IsAllTran) this.Ado.BeginTran(); if (this._IsOpen) this.Open(); _Context.Ado.IsEnableLogEvent = isLog; if (_CurrentConnectionConfig.AopEvents == null) _CurrentConnectionConfig.AopEvents = new AopEvents(); } public void BeginTran() { _IsAllTran = true; AllClientEach(it => it.Ado.BeginTran()); } public void BeginTran(IsolationLevel iso) { _IsAllTran = true; AllClientEach(it => it.Ado.BeginTran(iso)); } public async Task BeginTranAsync() { _IsAllTran = true; await AllClientEachAsync(async it => await it.Ado.BeginTranAsync()); } public async Task BeginTranAsync(IsolationLevel iso) { _IsAllTran = true; await AllClientEachAsync(async it => await it.Ado.BeginTranAsync(iso)); } public void CommitTran() { this.Context.Ado.CommitTran(); AllClientEach(it => { try { it.Ado.CommitTran(); } catch { SugarRetry.Execute(() => it.Ado.CommitTran(), new TimeSpan(0, 0, 5), 3); } }); _IsAllTran = false; } public async Task CommitTranAsync() { await this.Context.Ado.CommitTranAsync(); await AllClientEachAsync(async it => { try { await it.Ado.CommitTranAsync(); } catch { SugarRetry.Execute(() => it.Ado.CommitTran(), new TimeSpan(0, 0, 5), 3); } }); _IsAllTran = false; } public DbResult UseTran(Action action, Action errorCallBack = null) { var result = new DbResult(); try { this.BeginTran(); if (action != null) action(); this.CommitTran(); result.Data = result.IsSuccess = true; } catch (Exception ex) { result.ErrorException = ex; result.ErrorMessage = ex.Message; result.IsSuccess = false; this.RollbackTran(); if (errorCallBack != null) { errorCallBack(ex); } } return result; } public async Task> UseTranAsync(Func action, Action errorCallBack = null) { var result = new DbResult(); try { await this.BeginTranAsync(); if (action != null) await action(); await this.CommitTranAsync(); result.Data = result.IsSuccess = true; } catch (Exception ex) { result.ErrorException = ex; result.ErrorMessage = ex.Message; result.IsSuccess = false; await this.RollbackTranAsync(); if (errorCallBack != null) { errorCallBack(ex); } } return result; } public DbResult UseTran(Func action, Action errorCallBack = null) { var result = new DbResult(); try { this.BeginTran(); if (action != null) result.Data = action(); this.CommitTran(); result.IsSuccess = true; } catch (Exception ex) { result.ErrorException = ex; result.ErrorMessage = ex.Message; result.IsSuccess = false; this.RollbackTran(); if (errorCallBack != null) { errorCallBack(ex); } } return result; } public async Task> UseTranAsync(Func> action, Action errorCallBack = null) { var result = new DbResult(); try { this.BeginTran(); T data=default(T); if (action != null) data = await action(); this.CommitTran(); result.IsSuccess = true; result.Data = data; } catch (Exception ex) { result.ErrorException = ex; result.ErrorMessage = ex.Message; result.IsSuccess = false; this.RollbackTran(); if (errorCallBack != null) { errorCallBack(ex); } } return result; } public void RollbackTran() { this.Context.Ado.RollbackTran(); AllClientEach(it => { try { it.Ado.RollbackTran(); } catch { SugarRetry.Execute(() => it.Ado.RollbackTran(), new TimeSpan(0, 0, 5), 3); } }); _IsAllTran = false; } public async Task RollbackTranAsync() { await this.Context.Ado.RollbackTranAsync(); await AllClientEachAsync(async it => { try { await it.Ado.RollbackTranAsync(); } catch { SugarRetry.Execute(() => it.Ado.RollbackTran(), new TimeSpan(0, 0, 5), 3); } }); _IsAllTran = false; } public void Close() { this.Context.Close(); AllClientEach(it => it.Close()); _IsOpen = false; } public void Open() { this.Context.Open(); _IsOpen = true; } #endregion #region IDispose public void Dispose() { AllClientEach(it => it.Ado.RollbackTran()); AllClientEach(it => it.Dispose()); } #endregion #region Cache public SugarCacheProvider DataCache { get { return this.Context.DataCache; } } #endregion #region Other method public DynamicBuilder DynamicBuilder() { return this.Context.DynamicBuilder(); } public void Tracking(T data) where T : class, new() { this.Context.Tracking(data); } public void ClearTracking() { this.Context.ClearTracking(); } public void Tracking(List datas) where T : class, new() { this.Context.Tracking(datas); } public SqlSugarClient CopyNew() { var result= new SqlSugarClient(UtilMethods.CopyConfig(this.Ado.Context.CurrentConnectionConfig)); result.QueryFilter = this.QueryFilter; if (_AllClients != null) { foreach (var item in _AllClients) { if (!result.IsAnyConnection(item.ConnectionConfig.ConfigId)) { result.AddConnection(UtilMethods.CopyConfig(item.ConnectionConfig)); } } } return result; } public DateTime GetDate() { return this.Context.GetDate(); } public void InitMappingInfo(Type type) { this.Context.InitMappingInfo(type); } public void InitMappingInfo() { this.Context.InitMappingInfo(typeof(T)); } #endregion #region Helper public Task AsyncLock(int timeOutSeconds = 30) { return this.Context.AsyncLock(timeOutSeconds); } public SplitTableContext SplitHelper() where T:class,new() { return this.Context.SplitHelper(); } public SplitTableContext SplitHelper(Type entityType) { return this.Context.SplitHelper(entityType); } public SplitTableContextResult SplitHelper(T data) where T : class, new() { return this.Context.SplitHelper(data); } public SplitTableContextResult SplitHelper(List dataList) where T : class, new() { return this.Context.SplitHelper(dataList); } private SqlSugarProvider GetContext() { SqlSugarProvider result = null; //if (IsSameThreadAndShard()) //{ // result = SameThreadAndShard(); //} //else if (IsNoSameThreadAndShard()) //{ // result = NoSameThreadAndShard(); //} //else //{ result = Synchronization(); //} ///Because SqlSugarScope implements thread safety //else if (IsSingleInstanceAsync()) //{ // result = Synchronization();//Async no support Single Instance //} //else if (IsAsync()) //{ // result = Synchronization(); //} //else //{ // StackTrace st = new StackTrace(true); // var methods = st.GetFrames(); // var isAsync = UtilMethods.IsAnyAsyncMethod(methods); // if (isAsync) // { // result = Synchronization(); // } // else // { // result = NoSameThread(); // } //} if (result.Root == null) { result.Root = this; } return result; } private SqlSugarProvider NoSameThreadAsync() { var result = GetCallContext(); return result; } private SqlSugarProvider NoSameThread() { if (CallContext.ContextList.Value == null) { var context = CopyClient(); AddCallContext(context); return context; } else { var result = GetCallContext(); if (result == null) { var copy = CopyClient(); AddCallContext(copy); return copy; } else { return result; } } } private void InitTenant() { if (this._AllClients == null) { this._AllClients = new List(); this._AllClients.Add(new SugarTenant() { ConnectionConfig = this.CurrentConnectionConfig, Context = this.Context }); } } private SqlSugarProvider Synchronization() { _Context.MappingColumns = _MappingColumns; _Context.MappingTables = _MappingTables; _Context.IgnoreColumns = _IgnoreColumns; _Context.IgnoreInsertColumns = _IgnoreInsertColumns; return _Context; } private SqlSugarProvider NoSameThreadAndShard() { if (CallContext.ContextList.Value.IsNullOrEmpty()) { var copy = CopyClient(); AddCallContext(copy); return copy; } else { var result = GetCallContext(); if (result == null) { var copy = CopyClient(); AddCallContext(copy); return copy; } else { return result; } } } private SqlSugarProvider SameThreadAndShard() { if (CallContext.ContextList.Value.IsNullOrEmpty()) { AddCallContext(_Context); return _Context; } else { var result = GetCallContext(); if (result == null) { var copy = CopyClient(); AddCallContext(copy); return copy; } else { return result; } } } private bool IsAsync() { return AsyncId != null; } private bool IsSingleInstanceAsync() { return IsSingleInstance == true && AsyncId != null; } private bool IsSynchronization() { return _ThreadId == Thread.CurrentThread.ManagedThreadId.ToString(); } //private bool IsNoSameThreadAndShard() //{ // return CurrentConnectionConfig.IsShardSameThread && _ThreadId != Thread.CurrentThread.ManagedThreadId.ToString(); //} //private bool IsSameThreadAndShard() //{ // return CurrentConnectionConfig.IsShardSameThread && _ThreadId == Thread.CurrentThread.ManagedThreadId.ToString(); //} private SqlSugarProvider CopyClient() { var result = new SqlSugarProvider(this.CurrentConnectionConfig); result.MappingColumns = _MappingColumns; result.MappingTables = _MappingTables; result.IgnoreColumns = _IgnoreColumns; result.IgnoreInsertColumns = _IgnoreInsertColumns; return result; } private void AddCallContext(SqlSugarProvider context) { CallContext.ContextList.Value = new List(); CallContext.ContextList.Value.Add(context); } private SqlSugarProvider GetCallContext() { return CallContext.ContextList.Value.FirstOrDefault(it => it.CurrentConnectionConfig.DbType == _Context.CurrentConnectionConfig.DbType && it.CurrentConnectionConfig.ConnectionString == _Context.CurrentConnectionConfig.ConnectionString && it.CurrentConnectionConfig.InitKeyType == _Context.CurrentConnectionConfig.InitKeyType && it.CurrentConnectionConfig.IsAutoCloseConnection == _Context.CurrentConnectionConfig.IsAutoCloseConnection ); } protected virtual void InitContext(ConnectionConfig config) { var aopIsNull = config.AopEvents == null; if (aopIsNull) { config.AopEvents = new AopEvents(); } _Context = new SqlSugarProvider(config); if (!aopIsNull) _Context.Ado.IsEnableLogEvent = true; this.CurrentConnectionConfig = config; _ThreadId = Thread.CurrentThread.ManagedThreadId.ToString(); if (this.MappingTables == null) this.MappingTables = new MappingTableList(); if (this.MappingColumns == null) this.MappingColumns = new MappingColumnList(); if (this.IgnoreColumns == null) this.IgnoreColumns = new IgnoreColumnList(); if (this.IgnoreInsertColumns == null) this.IgnoreInsertColumns = new IgnoreColumnList(); } private void InitConfigs(List configs) { foreach (var item in configs) { if (item.ConfigId == null) { item.ConfigId = ""; } } } private void AllClientEach(Action action) { if (this._AllClients == null) { this._AllClients = new List(); this._AllClients.Add(new SugarTenant() { ConnectionConfig=this.CurrentConnectionConfig, Context=this.Context }); } if (_AllClients.HasValue()) { foreach (var item in _AllClients.Where(it => it.Context.HasValue())) { action(item.Context); } } } private async Task AllClientEachAsync(Func action) { if (this._AllClients == null) { this._AllClients = new List(); this._AllClients.Add(new SugarTenant() { ConnectionConfig = this.CurrentConnectionConfig, Context = this.Context }); } if (_AllClients.HasValue()) { foreach (var item in _AllClients.Where(it => it.Context.HasValue())) { await action(item.Context); } } } private void InitTenant(SugarTenant Tenant) { if (Tenant.Context == null) { Tenant.Context = new SqlSugarProvider(Tenant.ConnectionConfig); } _Context = Tenant.Context; this.CurrentConnectionConfig = Tenant.ConnectionConfig; } #endregion #region Tenant Crud public ISugarQueryable QueryableWithAttr() { var result= this.GetConnectionWithAttr().Queryable(); result.QueryBuilder.IsCrossQueryWithAttr= true; return result; } public IInsertable InsertableWithAttr(T insertObj) where T : class, new() { var result= this.GetConnectionWithAttr().Insertable(insertObj); result.InsertBuilder.IsWithAttr = true; return result; } public IInsertable InsertableWithAttr(List insertObjs) where T : class, new() { var result= this.GetConnectionWithAttr().Insertable(insertObjs); result.InsertBuilder.IsWithAttr = true; return result; } public IUpdateable UpdateableWithAttr(T updateObj) where T : class, new() { return this.GetConnectionWithAttr().Updateable(updateObj); } public IUpdateable UpdateableWithAttr() where T : class, new() { return this.GetConnectionWithAttr().Updateable(); } public IUpdateable UpdateableWithAttr(List updateObjs) where T : class, new() { return this.GetConnectionWithAttr().Updateable(updateObjs); } public IDeleteable DeleteableWithAttr(T deleteObject) where T : class, new() { return this.GetConnectionWithAttr().Deleteable(deleteObject); } public IDeleteable DeleteableWithAttr() where T : class, new() { return this.GetConnectionWithAttr().Deleteable(); } public IDeleteable DeleteableWithAttr(List deleteObjects) where T : class, new() { return this.GetConnectionWithAttr().Deleteable(deleteObjects); } #endregion } }