diff --git a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableExecuteSql.cs b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableExecuteSql.cs new file mode 100644 index 000000000..acb77353b --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableExecuteSql.cs @@ -0,0 +1,573 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; +using System.Reflection; +using System.Dynamic; +using System.Threading.Tasks; + +namespace SqlSugar +{ + + public partial class QueryableProvider : QueryableAccessory, ISugarQueryable + { + public virtual int Count() + { + if (this.QueryBuilder.Skip == null && + this.QueryBuilder.Take == null && + this.QueryBuilder.OrderByValue == null && + this.QueryBuilder.PartitionByValue == null && + this.QueryBuilder.SelectValue == null && + this.QueryBuilder.Includes == null && + this.QueryBuilder.IsDistinct == false) + { + + return this.Clone().Select(" COUNT(1) ").ToList().FirstOrDefault(); + } + MappingTableList expMapping; + int result; + _CountBegin(out expMapping, out result); + if (IsCache) + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => { return GetCount(); }, CacheTime, this.Context, CacheKey); + } + else + { + result = GetCount(); + } + _CountEnd(expMapping); + return result; + } + + public virtual int Count(Expression> expression) + { + _Where(expression); + var result = Count(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + + public virtual TResult Max(string maxField) + { + this.Select(string.Format(QueryBuilder.MaxTemplate, maxField)); + var result = this._ToList().SingleOrDefault(); + return result; + } + public virtual TResult Max(Expression> expression) + { + return _Max(expression); + } + + public virtual TResult Min(string minField) + { + this.Select(string.Format(QueryBuilder.MinTemplate, minField)); + var result = this._ToList().SingleOrDefault(); + return result; + } + public virtual TResult Min(Expression> expression) + { + return _Min(expression); + } + + public virtual TResult Sum(string sumField) + { + this.Select(string.Format(QueryBuilder.SumTemplate, sumField)); + var result = this._ToList().SingleOrDefault(); + return result; + } + public virtual TResult Sum(Expression> expression) + { + return _Sum(expression); + } + + public virtual TResult Avg(string avgField) + { + this.Select(string.Format(QueryBuilder.AvgTemplate, avgField)); + var result = this._ToList().SingleOrDefault(); + return result; + } + public virtual TResult Avg(Expression> expression) + { + return _Avg(expression); + } + public virtual T[] ToArray() + { + + var result = this.ToList(); + if (result.HasValue()) + return result.ToArray(); + else + return null; + } + + public virtual string ToJson() + { + if (IsCache) + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + var result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => + { + return this.Context.Utilities.SerializeObject(this.ToList(), typeof(T)); + }, CacheTime, this.Context, CacheKey); + return result; + } + else + { + return this.Context.Utilities.SerializeObject(this.ToList(), typeof(T)); + } + } + public virtual string ToJsonPage(int pageIndex, int pageSize) + { + return this.Context.Utilities.SerializeObject(this.ToPageList(pageIndex, pageSize), typeof(T)); + } + public virtual string ToJsonPage(int pageIndex, int pageSize, ref int totalNumber) + { + return this.Context.Utilities.SerializeObject(this.ToPageList(pageIndex, pageSize, ref totalNumber), typeof(T)); + } + public virtual DataTable ToPivotTable(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + return this.ToList().ToPivotTable(columnSelector, rowSelector, dataSelector); + } + public virtual List ToPivotList(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + return this.ToList().ToPivotList(columnSelector, rowSelector, dataSelector); + } + public virtual string ToPivotJson(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) + { + var list = this.ToPivotList(columnSelector, rowSelector, dataSelector); + return this.Context.Utilities.SerializeObject(list); + } + public List ToChildList(Expression> parentIdExpression, object primaryKeyValue, bool isContainOneself = true) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = GetTreeKey(entity); + var list = this.ToList(); + return GetChildList(parentIdExpression, pk, list, primaryKeyValue, isContainOneself); + } + + public List ToParentList(Expression> parentIdExpression, object primaryKeyValue) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var isTreeKey = entity.Columns.Any(it => it.IsTreeKey); + if (isTreeKey) + { + return _ToParentListByTreeKey(parentIdExpression, primaryKeyValue); + } + List result = new List() { }; + Check.Exception(entity.Columns.Where(it => it.IsPrimarykey).Count() == 0, "No Primary key"); + var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; + var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); + var parentPropertyName = ParentInfo.DbColumnName; + var tableName = this.QueryBuilder.GetTableNameString; + if (this.QueryBuilder.IsSingle() == false) + { + if (this.QueryBuilder.JoinQueryInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + if (this.QueryBuilder.EasyJoinInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + } + var current = this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingle(primaryKeyValue); + if (current != null) + { + result.Add(current); + object parentId = ParentInfo.PropertyInfo.GetValue(current, null); + int i = 0; + while (parentId != null && this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).In(parentId).Any()) + { + Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0")); + var parent = this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingle(parentId); + result.Add(parent); + parentId = ParentInfo.PropertyInfo.GetValue(parent, null); + ++i; + } + } + return result; + } + + public List ToTree(Expression>> childListExpression, Expression> parentIdExpression, object rootValue) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = GetTreeKey(entity); + var list = this.ToList(); + return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue); + } + + public virtual DataTable ToDataTable() + { + QueryBuilder.ResultType = typeof(SugarCacheDataTable); + InitMapping(); + var sqlObj = this.ToSql(); + RestoreMapping(); + DataTable result = null; + bool isChangeQueryableMasterSlave = GetIsMasterQuery(); + bool isChangeQueryableSlave = GetIsSlaveQuery(); + if (IsCache) + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => { return this.Db.GetDataTable(sqlObj.Key, sqlObj.Value.ToArray()); }, CacheTime, this.Context, CacheKey); + } + else + { + result = this.Db.GetDataTable(sqlObj.Key, sqlObj.Value.ToArray()); + } + RestChangeMasterQuery(isChangeQueryableMasterSlave); + RestChangeSlaveQuery(isChangeQueryableSlave); + return result; + } + public virtual DataTable ToDataTablePage(int pageIndex, int pageSize) + { + if (pageIndex == 0) + pageIndex = 1; + if (QueryBuilder.PartitionByValue.HasValue()) + { + QueryBuilder.ExternalPageIndex = pageIndex; + QueryBuilder.ExternalPageSize = pageSize; + } + else + { + QueryBuilder.Skip = (pageIndex - 1) * pageSize; + QueryBuilder.Take = pageSize; + } + return ToDataTable(); + } + public virtual DataTable ToDataTablePage(int pageIndex, int pageSize, ref int totalNumber) + { + _RestoreMapping = false; + totalNumber = this.Clone().Count(); + _RestoreMapping = true; + var result = this.Clone().ToDataTablePage(pageIndex, pageSize); + return result; + } + public virtual DataTable ToDataTablePage(int pageIndex, int pageSize, ref int totalNumber, ref int totalPage) + { + var result = ToDataTablePage(pageIndex, pageSize, ref totalNumber); + totalPage = (totalNumber + pageSize - 1) / pageSize; + return result; + } + + public Dictionary ToDictionary(Expression> key, Expression> value) + { + this.QueryBuilder.ResultType = typeof(SugarCacheDictionary); + var keyName = QueryBuilder.GetExpressionValue(key, ResolveExpressType.FieldSingle).GetResultString(); + var valueName = QueryBuilder.GetExpressionValue(value, ResolveExpressType.FieldSingle).GetResultString(); + if (this.QueryBuilder.IsSingle() == false) + { + keyName = this.QueryBuilder.TableShortName + "." + keyName; + valueName = this.QueryBuilder.TableShortName + "." + valueName; + } + var result = this.Select>(keyName + "," + valueName).ToList().ToDictionary(it => it.Key.ObjToString(), it => it.Value); + return result; + } + + public List> ToDictionaryList() + { + var list = this.ToList(); + if (list == null) + return null; + else + return this.Context.Utilities.DeserializeObject>>(this.Context.Utilities.SerializeObject(list)); + } + public async Task>> ToDictionaryListAsync() + { + var list = await this.ToListAsync(); + if (list == null) + return null; + else + return this.Context.Utilities.DeserializeObject>>(this.Context.Utilities.SerializeObject(list)); + } + + public virtual List ToList() + { + InitMapping(); + return _ToList(); + } + public List SetContext(Expression> thisFiled, Expression> mappingFiled, ParameterT parameter) + { + if (parameter == null) + { + return new List(); + } + List result = new List(); + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext; + var list = queryableContext.list; + var pkName = ""; + if ((mappingFiled as LambdaExpression).Body is UnaryExpression) + { + pkName = (((mappingFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name; + } + else + { + pkName = ((mappingFiled as LambdaExpression).Body as MemberExpression).Member.Name; + } + var key = thisFiled.ToString() + mappingFiled.ToString() + typeof(ParameterT).FullName + typeof(T).FullName; + var ids = list.Where(it => it != null).Select(it => it.GetType().GetProperty(pkName).GetValue(it)).Distinct().ToArray(); + if (queryableContext.TempChildLists == null) + queryableContext.TempChildLists = new Dictionary(); + if (list != null && queryableContext.TempChildLists.ContainsKey(key)) + { + result = (List)queryableContext.TempChildLists[key]; + } + else + { + if (queryableContext.TempChildLists == null) + queryableContext.TempChildLists = new Dictionary(); + this.Context.Utilities.PageEach(ids, 200, pageIds => + { + result.AddRange(this.Clone().In(thisFiled, pageIds).ToList()); + }); + queryableContext.TempChildLists[key] = result; + } + var name = ""; + if ((thisFiled as LambdaExpression).Body is UnaryExpression) + { + name = (((thisFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name; + } + else + { + name = ((thisFiled as LambdaExpression).Body as MemberExpression).Member.Name; + } + var pkValue = parameter.GetType().GetProperty(pkName).GetValue(parameter); + result = result.Where(it => it.GetType().GetProperty(name).GetValue(it).ObjToString() == pkValue.ObjToString()).ToList(); + return result; + } + public List SetContext(Expression> thisFiled1, Expression> mappingFiled1, + Expression> thisFiled2, Expression> mappingFiled2, + ParameterT parameter) + { + if (parameter == null) + { + return new List(); + } + var rightEntity = this.Context.EntityMaintenance.GetEntityInfo(); + var leftEntity = this.Context.EntityMaintenance.GetEntityInfo(); + List result = new List(); + var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext; + var list = queryableContext.list; + var key = thisFiled1.ToString() + mappingFiled1.ToString() + + thisFiled2.ToString() + mappingFiled2.ToString() + + typeof(ParameterT).FullName + typeof(T).FullName; + MappingFieldsHelper fieldsHelper = new MappingFieldsHelper(); + var mappings = new List() { + new MappingFieldsExpression(){ + LeftColumnExpression=thisFiled1, + LeftEntityColumn=leftEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(thisFiled1)), + RightColumnExpression=mappingFiled1, + RightEntityColumn=rightEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(mappingFiled1)) + }, + new MappingFieldsExpression(){ + LeftColumnExpression=thisFiled2, + LeftEntityColumn=leftEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(thisFiled2)), + RightColumnExpression=mappingFiled2, + RightEntityColumn=rightEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(mappingFiled2)) + } + }; + var conditionals = fieldsHelper.GetMppingSql(list.Cast().ToList(), mappings); + if (queryableContext.TempChildLists == null) + queryableContext.TempChildLists = new Dictionary(); + if (list != null && queryableContext.TempChildLists.ContainsKey(key)) + { + result = (List)queryableContext.TempChildLists[key]; + } + else + { + result = this.Clone().Where(conditionals, true).ToList(); + queryableContext.TempChildLists[key] = result; + } + List listObj = result.Select(it => (object)it).ToList(); + object obj = (object)parameter; + var newResult = fieldsHelper.GetSetList(obj, listObj, mappings).Select(it => (T)it).ToList(); + return newResult; + } + + public virtual void ForEach(Action action, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null) + { + Check.Exception(this.QueryBuilder.Skip > 0 || this.QueryBuilder.Take > 0, ErrorMessage.GetThrowMessage("no support Skip take, use PageForEach", "不支持Skip Take,请使用 Queryale.PageForEach")); + var totalNumber = 0; + var totalPage = 1; + for (int i = 1; i <= totalPage; i++) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + var queryable = this.Clone(); + var page = + totalPage == 1 ? + queryable.ToPageList(i, singleMaxReads, ref totalNumber, ref totalPage) : + queryable.ToPageList(i, singleMaxReads); + foreach (var item in page) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + action.Invoke(item); + } + } + } + + public virtual void ForEachByPage(Action action, int pageIndex, int pageSize, ref int totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null) + { + int count = this.Clone().Count(); + if (count > 0) + { + if (pageSize > singleMaxReads && count - ((pageIndex - 1) * pageSize) > singleMaxReads) + { + Int32 Skip = (pageIndex - 1) * pageSize; + Int32 NowCount = count - Skip; + Int32 number = 0; + if (NowCount > pageSize) NowCount = pageSize; + while (NowCount > 0) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + if (number + singleMaxReads > pageSize) singleMaxReads = NowCount; + foreach (var item in this.Clone().Skip(Skip).Take(singleMaxReads).ToList()) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + action.Invoke(item); + } + NowCount -= singleMaxReads; + Skip += singleMaxReads; + number += singleMaxReads; + } + } + else + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + foreach (var item in this.Clone().ToPageList(pageIndex, pageSize)) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + action.Invoke(item); + } + } + } + totalNumber = count; + } + + public List ToOffsetPage(int pageIndex, int pageSize) + { + if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) + { + this.QueryBuilder.Offset = "true"; + return this.ToPageList(pageIndex, pageSize); + } + else + { + _ToOffsetPage(pageIndex, pageSize); + return this.ToList(); + } + } + public List ToOffsetPage(int pageIndex, int pageSize, ref int totalNumber) + { + if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) + { + this.QueryBuilder.Offset = "true"; + return this.ToPageList(pageIndex, pageSize, ref totalNumber); + } + else + { + totalNumber = this.Clone().Count(); + _ToOffsetPage(pageIndex, pageSize); + return this.Clone().ToList(); + } + } + public Task> ToOffsetPageAsync(int pageIndex, int pageSize) + { + if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) + { + this.QueryBuilder.Offset = "true"; + return this.ToPageListAsync(pageIndex, pageSize); + } + else + { + _ToOffsetPage(pageIndex, pageSize); + return this.ToListAsync(); + } + } + + public virtual List ToPageList(int pageIndex, int pageSize) + { + pageIndex = _PageList(pageIndex, pageSize); + return ToList(); + } + public virtual List ToPageList(int pageIndex, int pageSize, ref int totalNumber, Expression> expression) + { + if (this.QueryBuilder.Includes != null && this.QueryBuilder.Includes.Count > 0) + { + if (pageIndex == 0) + pageIndex = 1; + var list = this.Clone().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(expression); + var countQueryable = this.Clone(); + countQueryable.QueryBuilder.Includes = null; + totalNumber = countQueryable.Count(); + return list; + } + else + { + var list = this.Select(expression).ToPageList(pageIndex, pageSize, ref totalNumber).ToList(); + return list; + } + } + public virtual List ToPageList(int pageIndex, int pageSize, ref int totalNumber) + { + var oldMapping = this.Context.MappingTables; + var countQueryable = this.Clone(); + if (countQueryable.QueryBuilder.Offset == "true") + { + countQueryable.QueryBuilder.Offset = null; + } + totalNumber = countQueryable.Count(); + this.Context.MappingTables = oldMapping; + return this.Clone().ToPageList(pageIndex, pageSize); + } + public virtual List ToPageList(int pageIndex, int pageSize, ref int totalNumber, ref int totalPage) + { + var result = ToPageList(pageIndex, pageSize, ref totalNumber); + totalPage = (totalNumber + pageSize - 1) / pageSize; + return result; + } + public virtual string ToSqlString() + { + var sqlObj = this.Clone().ToSql(); + var result = sqlObj.Key; + if (result == null) return null; + result = UtilMethods.GetSqlString(this.Context.CurrentConnectionConfig, sqlObj); + return result; + } + + + public virtual KeyValuePair> ToSql() + { + if (!QueryBuilder.IsClone) + { + var newQueryable = this.Clone(); + newQueryable.QueryBuilder.IsClone = true; + return newQueryable.ToSql(); + } + else + { + return _ToSql(); + } + } + public string ToClassString(string className) + { + List columns = new List(); + var properties = typeof(T).GetProperties(); + foreach (var item in properties) + { + columns.Add(new DbColumnInfo() + { + DbColumnName = item.Name, + PropertyName = UtilMethods.GetUnderType(item.PropertyType).Name, + PropertyType = UtilMethods.GetUnderType(item.PropertyType) + }); + } + var result = ((this.Context.DbFirst) as DbFirstProvider).GetClassString(columns, ref className); + return result; + } + } +} diff --git a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableExecuteSqlAsync.cs b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableExecuteSqlAsync.cs new file mode 100644 index 000000000..1b0ab5e91 --- /dev/null +++ b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableExecuteSqlAsync.cs @@ -0,0 +1,542 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Text.RegularExpressions; +using System.Reflection; +using System.Dynamic; +using System.Threading.Tasks; + +namespace SqlSugar +{ + + public partial class QueryableProvider : QueryableAccessory, ISugarQueryable + { + public async virtual Task ToArrayAsync() + { + + var result = await this.ToListAsync(); + if (result.HasValue()) + return result.ToArray(); + else + return null; + } + public virtual async Task InSingleAsync(object pkValue) + { + Check.Exception(this.QueryBuilder.SelectValue.HasValue(), "'InSingle' and' Select' can't be used together,You can use .Select(it=>...).Single(it.id==1)"); + var list = await In(pkValue).ToListAsync(); + if (list == null) return default(T); + else return list.SingleOrDefault(); + } + public async Task SingleAsync() + { + if (QueryBuilder.OrderByValue.IsNullOrEmpty()) + { + QueryBuilder.OrderByValue = QueryBuilder.DefaultOrderByTemplate; + } + var oldSkip = QueryBuilder.Skip; + var oldTake = QueryBuilder.Take; + var oldOrderBy = QueryBuilder.OrderByValue; + QueryBuilder.Skip = null; + QueryBuilder.Take = null; + QueryBuilder.OrderByValue = null; + var result = await this.ToListAsync(); + QueryBuilder.Skip = oldSkip; + QueryBuilder.Take = oldTake; + QueryBuilder.OrderByValue = oldOrderBy; + if (result == null || result.Count == 0) + { + return default(T); + } + else if (result.Count == 2) + { + Check.Exception(true, ErrorMessage.GetThrowMessage(".Single() result must not exceed one . You can use.First()", "使用single查询结果集不能大于1,适合主键查询,如果大于1你可以使用Queryable.First")); + return default(T); + } + else + { + return result.SingleOrDefault(); + } + } + + public async Task SingleAsync(Expression> expression) + { + _Where(expression); + var result = await SingleAsync(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + + public async Task FirstAsync() + { + if (QueryBuilder.OrderByValue.IsNullOrEmpty()) + { + QueryBuilder.OrderByValue = QueryBuilder.DefaultOrderByTemplate; + } + if (QueryBuilder.Skip.HasValue) + { + QueryBuilder.Take = 1; + var list = await this.ToListAsync(); + return list.FirstOrDefault(); + } + else + { + QueryBuilder.Skip = 0; + QueryBuilder.Take = 1; + var result = await this.ToListAsync(); + if (result.HasValue()) + return result.FirstOrDefault(); + else + return default(T); + } + } + + public async Task FirstAsync(Expression> expression) + { + _Where(expression); + var result = await FirstAsync(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + + public async Task AnyAsync(Expression> expression) + { + _Where(expression); + var result = await AnyAsync(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + + public async Task AnyAsync() + { + return await this.CountAsync() > 0; + } + + public async Task CountAsync() + { + if (this.QueryBuilder.Skip == null && + this.QueryBuilder.Take == null && + this.QueryBuilder.OrderByValue == null && + this.QueryBuilder.PartitionByValue == null && + this.QueryBuilder.SelectValue == null && + this.QueryBuilder.Includes == null && + this.QueryBuilder.IsDistinct == false) + { + var list = await this.Clone().Select(" COUNT(1) ").ToListAsync(); + return list.FirstOrDefault(); + } + MappingTableList expMapping; + int result; + _CountBegin(out expMapping, out result); + if (IsCache) + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => { return GetCount(); }, CacheTime, this.Context, CacheKey); + } + else + { + result = await GetCountAsync(); + } + _CountEnd(expMapping); + return result; + } + public async Task CountAsync(Expression> expression) + { + _Where(expression); + var result = await CountAsync(); + this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); + return result; + } + public async Task MaxAsync(string maxField) + { + this.Select(string.Format(QueryBuilder.MaxTemplate, maxField)); + var list = await this._ToListAsync(); + var result = list.SingleOrDefault(); + return result; + } + + public Task MaxAsync(Expression> expression) + { + return _MaxAsync(expression); + } + + public async Task MinAsync(string minField) + { + this.Select(string.Format(QueryBuilder.MinTemplate, minField)); + var list = await this._ToListAsync(); + var result = list.SingleOrDefault(); + return result; + } + + public Task MinAsync(Expression> expression) + { + return _MinAsync(expression); + } + + public async Task SumAsync(string sumField) + { + this.Select(string.Format(QueryBuilder.SumTemplate, sumField)); + var list = await this._ToListAsync(); + var result = list.SingleOrDefault(); + return result; + } + + public Task SumAsync(Expression> expression) + { + return _SumAsync(expression); + } + + public async Task AvgAsync(string avgField) + { + this.Select(string.Format(QueryBuilder.AvgTemplate, avgField)); + var list = await this._ToListAsync(); + var result = list.SingleOrDefault(); + return result; + } + + public Task AvgAsync(Expression> expression) + { + return _AvgAsync(expression); + } + + public Task> ToListAsync() + { + InitMapping(); + return _ToListAsync(); + } + public Task> ToPageListAsync(int pageIndex, int pageSize) + { + pageIndex = _PageList(pageIndex, pageSize); + return ToListAsync(); + } + public async virtual Task> ToPageListAsync(int pageIndex, int pageSize, RefAsync totalNumber, Expression> expression) + { + if (this.QueryBuilder.Includes != null && this.QueryBuilder.Includes.Count > 0) + { + if (pageIndex == 0) + pageIndex = 1; + var list = await this.Clone().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(expression); + var countQueryable = this.Clone(); + countQueryable.QueryBuilder.Includes = null; + totalNumber.Value = await countQueryable.CountAsync(); + return list; + } + else + { + var list = await this.Select(expression).ToPageListAsync(pageIndex, pageSize, totalNumber); + return list; + } + } + public async Task> ToPageListAsync(int pageIndex, int pageSize, RefAsync totalNumber) + { + var oldMapping = this.Context.MappingTables; + var countQueryable = this.Clone(); + if (countQueryable.QueryBuilder.Offset == "true") + { + countQueryable.QueryBuilder.Offset = null; + } + totalNumber.Value = await countQueryable.CountAsync(); + this.Context.MappingTables = oldMapping; + return await this.Clone().ToPageListAsync(pageIndex, pageSize); + } + public async Task> ToPageListAsync(int pageNumber, int pageSize, RefAsync totalNumber, RefAsync totalPage) + { + var result = await ToPageListAsync(pageNumber, pageSize, totalNumber); + totalPage.Value = (totalNumber.Value + pageSize - 1) / pageSize; + return result; + } + public async Task ToJsonAsync() + { + if (IsCache) + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + var result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => + { + return this.Context.Utilities.SerializeObject(this.ToList(), typeof(T)); + }, CacheTime, this.Context, CacheKey); + return result; + } + else + { + return this.Context.Utilities.SerializeObject(await this.ToListAsync(), typeof(T)); + } + } + public async Task ToJsonPageAsync(int pageIndex, int pageSize) + { + return this.Context.Utilities.SerializeObject(await this.ToPageListAsync(pageIndex, pageSize), typeof(T)); + } + public async Task ToJsonPageAsync(int pageIndex, int pageSize, RefAsync totalNumber) + { + var oldMapping = this.Context.MappingTables; + totalNumber.Value = await this.Clone().CountAsync(); + this.Context.MappingTables = oldMapping; + return await this.Clone().ToJsonPageAsync(pageIndex, pageSize); + } + public async Task ToDataTableAsync() + { + QueryBuilder.ResultType = typeof(SugarCacheDataTable); + InitMapping(); + var sqlObj = this._ToSql(); + RestoreMapping(); + DataTable result = null; + if (IsCache) + { + var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; + result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => { return this.Db.GetDataTable(sqlObj.Key, sqlObj.Value.ToArray()); }, CacheTime, this.Context, CacheKey); + } + else + { + result = await this.Db.GetDataTableAsync(sqlObj.Key, sqlObj.Value.ToArray()); + } + return result; + } + public Task ToDataTablePageAsync(int pageIndex, int pageSize) + { + pageIndex = _PageList(pageIndex, pageSize); + return ToDataTableAsync(); + } + public async Task ToDataTablePageAsync(int pageIndex, int pageSize, RefAsync totalNumber) + { + var oldMapping = this.Context.MappingTables; + totalNumber.Value = await this.Clone().CountAsync(); + this.Context.MappingTables = oldMapping; + return await this.Clone().ToDataTablePageAsync(pageIndex, pageSize); + } + public async Task> ToOffsetPageAsync(int pageIndex, int pageSize, RefAsync totalNumber) + { + if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) + { + this.QueryBuilder.Offset = "true"; + return await this.ToPageListAsync(pageIndex, pageSize, totalNumber); + } + else + { + totalNumber.Value = await this.Clone().CountAsync(); + _ToOffsetPage(pageIndex, pageSize); + return await this.Clone().ToListAsync(); + } + } + public virtual async Task ForEachAsync(Action action, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null) + { + Check.Exception(this.QueryBuilder.Skip > 0 || this.QueryBuilder.Take > 0, ErrorMessage.GetThrowMessage("no support Skip take, use PageForEach", "不支持Skip Take,请使用 Queryale.PageForEach")); + RefAsync totalNumber = 0; + RefAsync totalPage = 1; + for (int i = 1; i <= totalPage; i++) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + var queryable = this.Clone(); + var page = + totalPage == 1 ? + await queryable.ToPageListAsync(i, singleMaxReads, totalNumber, totalPage) : + await queryable.ToPageListAsync(i, singleMaxReads); + foreach (var item in page) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + action.Invoke(item); + } + } + } + public virtual async Task ForEachByPageAsync(Action action, int pageIndex, int pageSize, RefAsync totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null) + { + int count = this.Clone().Count(); + if (count > 0) + { + if (pageSize > singleMaxReads && count - ((pageIndex - 1) * pageSize) > singleMaxReads) + { + Int32 Skip = (pageIndex - 1) * pageSize; + Int32 NowCount = count - Skip; + Int32 number = 0; + if (NowCount > pageSize) NowCount = pageSize; + while (NowCount > 0) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + if (number + singleMaxReads > pageSize) singleMaxReads = NowCount; + foreach (var item in await this.Clone().Skip(Skip).Take(singleMaxReads).ToListAsync()) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + action.Invoke(item); + } + NowCount -= singleMaxReads; + Skip += singleMaxReads; + number += singleMaxReads; + } + } + else + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + foreach (var item in this.Clone().ToPageList(pageIndex, pageSize)) + { + if (cancellationTokenSource?.IsCancellationRequested == true) return; + action.Invoke(item); + } + } + } + totalNumber = count; + } + public async Task> SetContextAsync(Expression> thisFiled1, Expression> mappingFiled1, +Expression> thisFiled2, Expression> mappingFiled2, +ParameterT parameter) + { + if (parameter == null) + { + return new List(); + } + var rightEntity = this.Context.EntityMaintenance.GetEntityInfo(); + var leftEntity = this.Context.EntityMaintenance.GetEntityInfo(); + List result = new List(); + var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext; + var list = queryableContext.list; + var key = thisFiled1.ToString() + mappingFiled1.ToString() + + thisFiled2.ToString() + mappingFiled2.ToString() + + typeof(ParameterT).FullName + typeof(T).FullName; + MappingFieldsHelper fieldsHelper = new MappingFieldsHelper(); + var mappings = new List() { + new MappingFieldsExpression(){ + LeftColumnExpression=thisFiled1, + LeftEntityColumn=leftEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(thisFiled1)), + RightColumnExpression=mappingFiled1, + RightEntityColumn=rightEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(mappingFiled1)) + }, + new MappingFieldsExpression(){ + LeftColumnExpression=thisFiled2, + LeftEntityColumn=leftEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(thisFiled2)), + RightColumnExpression=mappingFiled2, + RightEntityColumn=rightEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(mappingFiled2)) + } + }; + var conditionals = fieldsHelper.GetMppingSql(list.Cast().ToList(), mappings); + if (queryableContext.TempChildLists == null) + queryableContext.TempChildLists = new Dictionary(); + if (list != null && queryableContext.TempChildLists.ContainsKey(key)) + { + result = (List)queryableContext.TempChildLists[key]; + } + else + { + result = await this.Clone().Where(conditionals, true).ToListAsync(); + queryableContext.TempChildLists[key] = result; + } + List listObj = result.Select(it => (object)it).ToList(); + object obj = (object)parameter; + var newResult = fieldsHelper.GetSetList(obj, listObj, mappings).Select(it => (T)it).ToList(); + return newResult; + } + + public async Task> SetContextAsync(Expression> thisFiled, Expression> mappingFiled, ParameterT parameter) + { + List result = new List(); + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext; + var list = queryableContext.list; + var pkName = ""; + if ((mappingFiled as LambdaExpression).Body is UnaryExpression) + { + pkName = (((mappingFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name; + } + else + { + pkName = ((mappingFiled as LambdaExpression).Body as MemberExpression).Member.Name; + } + var key = thisFiled.ToString() + mappingFiled.ToString() + typeof(ParameterT).FullName + typeof(T).FullName; + var ids = list.Select(it => it.GetType().GetProperty(pkName).GetValue(it)).ToArray(); + if (queryableContext.TempChildLists == null) + queryableContext.TempChildLists = new Dictionary(); + if (list != null && queryableContext.TempChildLists.ContainsKey(key)) + { + result = (List)queryableContext.TempChildLists[key]; + } + else + { + if (queryableContext.TempChildLists == null) + queryableContext.TempChildLists = new Dictionary(); + await this.Context.Utilities.PageEachAsync(ids, 200, async pageIds => + { + result.AddRange(await this.Clone().In(thisFiled, pageIds).ToListAsync()); + }); + queryableContext.TempChildLists[key] = result; + } + var name = ""; + if ((thisFiled as LambdaExpression).Body is UnaryExpression) + { + name = (((thisFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name; + } + else + { + name = ((thisFiled as LambdaExpression).Body as MemberExpression).Member.Name; + } + var pkValue = parameter.GetType().GetProperty(pkName).GetValue(parameter); + result = result.Where(it => it.GetType().GetProperty(name).GetValue(it).ObjToString() == pkValue.ObjToString()).ToList(); + return result; + } + public async Task> ToDictionaryAsync(Expression> key, Expression> value) + { + this.QueryBuilder.ResultType = typeof(SugarCacheDictionary); + var keyName = QueryBuilder.GetExpressionValue(key, ResolveExpressType.FieldSingle).GetResultString(); + var valueName = QueryBuilder.GetExpressionValue(value, ResolveExpressType.FieldSingle).GetResultString(); + var list = await this.Select>(keyName + "," + valueName).ToListAsync(); + var result = list.ToDictionary(it => it.Key.ObjToString(), it => it.Value); + return result; + } + + public async Task> ToTreeAsync(Expression>> childListExpression, Expression> parentIdExpression, object rootValue) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = GetTreeKey(entity); ; + var list = await this.ToListAsync(); + return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue); + } + + public async Task> ToParentListAsync(Expression> parentIdExpression, object primaryKeyValue) + { + List result = new List() { }; + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var isTreeKey = entity.Columns.Any(it => it.IsTreeKey); + if (isTreeKey) + { + return await _ToParentListByTreeKeyAsync(parentIdExpression, primaryKeyValue); + } + Check.Exception(entity.Columns.Where(it => it.IsPrimarykey).Count() == 0, "No Primary key"); + var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; + var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); + var parentPropertyName = ParentInfo.DbColumnName; + var tableName = this.QueryBuilder.GetTableNameString; + if (this.QueryBuilder.IsSingle() == false) + { + if (this.QueryBuilder.JoinQueryInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + if (this.QueryBuilder.EasyJoinInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + } + var current = await this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingleAsync(primaryKeyValue); + if (current != null) + { + result.Add(current); + object parentId = ParentInfo.PropertyInfo.GetValue(current, null); + int i = 0; + while (parentId != null && await this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).In(parentId).AnyAsync()) + { + Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0")); + var parent = await this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingleAsync(parentId); + result.Add(parent); + parentId = ParentInfo.PropertyInfo.GetValue(parent, null); + ++i; + } + } + return result; + } + public async Task> ToChildListAsync(Expression> parentIdExpression, object primaryKeyValue, bool isContainOneself = true) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var pk = GetTreeKey(entity); + var list = await this.ToListAsync(); + return GetChildList(parentIdExpression, pk, list, primaryKeyValue, isContainOneself); + } + } +} diff --git a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableHelper.cs b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableHelper.cs index 85fdf0abd..627922b35 100644 --- a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableHelper.cs +++ b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableHelper.cs @@ -14,7 +14,125 @@ namespace SqlSugar { public partial class QueryableProvider : QueryableAccessory, ISugarQueryable { - #region Private Methods + + private List _ToParentListByTreeKey(Expression> parentIdExpression, object primaryKeyValue) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var treeKey = entity.Columns.FirstOrDefault(it => it.IsTreeKey); + List result = new List() { }; + var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; + var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); + var parentPropertyName = ParentInfo.DbColumnName; + var tableName = this.QueryBuilder.GetTableNameString; + if (this.QueryBuilder.IsSingle() == false) + { + if (this.QueryBuilder.JoinQueryInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + if (this.QueryBuilder.EasyJoinInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + } + var current = this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = primaryKeyValue + "", + FieldName = treeKey.DbColumnName + } }).First(); + if (current != null) + { + result.Add(current); + object parentId = ParentInfo.PropertyInfo.GetValue(current, null); + int i = 0; + while (parentId != null && this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = parentId + "", + FieldName = treeKey.DbColumnName + } }).Any()) + { + Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0")); + var parent = this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = parentId + "", + FieldName = treeKey.DbColumnName + } }).First(); + result.Add(parent); + parentId = ParentInfo.PropertyInfo.GetValue(parent, null); + ++i; + } + } + return result; + } + + private async Task> _ToParentListByTreeKeyAsync(Expression> parentIdExpression, object primaryKeyValue) + { + var entity = this.Context.EntityMaintenance.GetEntityInfo(); + var treeKey = entity.Columns.FirstOrDefault(it => it.IsTreeKey); + List result = new List() { }; + var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; + var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); + var parentPropertyName = ParentInfo.DbColumnName; + var tableName = this.QueryBuilder.GetTableNameString; + if (this.QueryBuilder.IsSingle() == false) + { + if (this.QueryBuilder.JoinQueryInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + if (this.QueryBuilder.EasyJoinInfos.Count > 0) + { + tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; + } + } + var current = await this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = primaryKeyValue + "", + FieldName = treeKey.DbColumnName + } }).FirstAsync(); + if (current != null) + { + result.Add(current); + object parentId = ParentInfo.PropertyInfo.GetValue(current, null); + int i = 0; + while (parentId != null && await this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = parentId + "", + FieldName = treeKey.DbColumnName + } }).AnyAsync()) + { + Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0")); + var parent = await this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { + new ConditionalModel() + { + ConditionalType = ConditionalType.Equal, + CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, + FieldValue = parentId + "", + FieldName = treeKey.DbColumnName + } }).FirstAsync(); + result.Add(parent); + parentId = ParentInfo.PropertyInfo.GetValue(parent, null); + ++i; + } + } + return result; + } + public virtual KeyValuePair> _ToSql() { InitMapping(); @@ -1193,7 +1311,5 @@ namespace SqlSugar return cacheDurationInSeconds; } - - #endregion } } diff --git a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs index 3c591c41d..dde33bfe2 100644 --- a/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs +++ b/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs @@ -1217,1196 +1217,5 @@ namespace SqlSugar QueryBuilder.IsDistinct = true; return this; } - public virtual int Count() - { - if (this.QueryBuilder.Skip == null&& - this.QueryBuilder.Take == null&& - this.QueryBuilder.OrderByValue == null && - this.QueryBuilder.PartitionByValue == null&& - this.QueryBuilder.SelectValue==null&& - this.QueryBuilder.Includes == null&& - this.QueryBuilder.IsDistinct==false) - { - - return this.Clone().Select(" COUNT(1) ").ToList().FirstOrDefault(); - } - MappingTableList expMapping; - int result; - _CountBegin(out expMapping, out result); - if (IsCache) - { - var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; - result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => { return GetCount(); }, CacheTime, this.Context,CacheKey); - } - else - { - result = GetCount(); - } - _CountEnd(expMapping); - return result; - } - - public virtual int Count(Expression> expression) - { - _Where(expression); - var result = Count(); - this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); - return result; - } - - public virtual TResult Max(string maxField) - { - this.Select(string.Format(QueryBuilder.MaxTemplate, maxField)); - var result = this._ToList().SingleOrDefault(); - return result; - } - public virtual TResult Max(Expression> expression) - { - return _Max(expression); - } - - public virtual TResult Min(string minField) - { - this.Select(string.Format(QueryBuilder.MinTemplate, minField)); - var result = this._ToList().SingleOrDefault(); - return result; - } - public virtual TResult Min(Expression> expression) - { - return _Min(expression); - } - - public virtual TResult Sum(string sumField) - { - this.Select(string.Format(QueryBuilder.SumTemplate, sumField)); - var result = this._ToList().SingleOrDefault(); - return result; - } - public virtual TResult Sum(Expression> expression) - { - return _Sum(expression); - } - - public virtual TResult Avg(string avgField) - { - this.Select(string.Format(QueryBuilder.AvgTemplate, avgField)); - var result = this._ToList().SingleOrDefault(); - return result; - } - public virtual TResult Avg(Expression> expression) - { - return _Avg(expression); - } - public virtual T[] ToArray() - { - - var result = this.ToList(); - if (result.HasValue()) - return result.ToArray(); - else - return null; - } - public async virtual Task ToArrayAsync() - { - - var result =await this.ToListAsync(); - if (result.HasValue()) - return result.ToArray(); - else - return null; - } - public virtual string ToJson() - { - if (IsCache) - { - var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; - var result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => - { - return this.Context.Utilities.SerializeObject(this.ToList(), typeof(T)); - }, CacheTime, this.Context,CacheKey); - return result; - } - else - { - return this.Context.Utilities.SerializeObject(this.ToList(), typeof(T)); - } - } - public virtual string ToJsonPage(int pageIndex, int pageSize) - { - return this.Context.Utilities.SerializeObject(this.ToPageList(pageIndex, pageSize), typeof(T)); - } - public virtual string ToJsonPage(int pageIndex, int pageSize, ref int totalNumber) - { - return this.Context.Utilities.SerializeObject(this.ToPageList(pageIndex, pageSize, ref totalNumber), typeof(T)); - } - public virtual DataTable ToPivotTable(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) - { - return this.ToList().ToPivotTable(columnSelector,rowSelector,dataSelector); - } - public virtual List ToPivotList(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) - { - return this.ToList().ToPivotList(columnSelector, rowSelector, dataSelector); - } - public virtual string ToPivotJson(Func columnSelector, Expression> rowSelector, Func, TData> dataSelector) - { - var list= this.ToPivotList(columnSelector, rowSelector, dataSelector); - return this.Context.Utilities.SerializeObject(list); - } - public List ToChildList(Expression> parentIdExpression, object primaryKeyValue, bool isContainOneself = true) - { - var entity = this.Context.EntityMaintenance.GetEntityInfo(); - var pk = GetTreeKey(entity); - var list = this.ToList(); - return GetChildList(parentIdExpression, pk, list, primaryKeyValue, isContainOneself); - } - public async Task> ToChildListAsync(Expression> parentIdExpression, object primaryKeyValue, bool isContainOneself=true) - { - var entity = this.Context.EntityMaintenance.GetEntityInfo(); - var pk = GetTreeKey(entity); - var list = await this.ToListAsync(); - return GetChildList(parentIdExpression, pk, list, primaryKeyValue, isContainOneself); - } - public List ToParentList(Expression> parentIdExpression, object primaryKeyValue) - { - var entity = this.Context.EntityMaintenance.GetEntityInfo(); - var isTreeKey = entity.Columns.Any(it => it.IsTreeKey); - if (isTreeKey) - { - return _ToParentListByTreeKey(parentIdExpression,primaryKeyValue); - } - List result = new List() { }; - Check.Exception(entity.Columns.Where(it => it.IsPrimarykey).Count() == 0, "No Primary key"); - var parentIdName =UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; - var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); - var parentPropertyName= ParentInfo.DbColumnName; - var tableName= this.QueryBuilder.GetTableNameString; - if (this.QueryBuilder.IsSingle() == false) - { - if (this.QueryBuilder.JoinQueryInfos.Count>0) - { - tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; - } - if (this.QueryBuilder.EasyJoinInfos.Count>0) - { - tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; - } - } - var current = this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingle(primaryKeyValue); - if (current != null) - { - result.Add(current); - object parentId = ParentInfo.PropertyInfo.GetValue(current,null); - int i = 0; - while (parentId!=null&&this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).In(parentId).Any()) - { - Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0")); - var parent = this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingle(parentId); - result.Add(parent); - parentId= ParentInfo.PropertyInfo.GetValue(parent, null); - ++i; - } - } - return result; - } - - private List _ToParentListByTreeKey(Expression> parentIdExpression, object primaryKeyValue) - { - var entity = this.Context.EntityMaintenance.GetEntityInfo(); - var treeKey = entity.Columns.FirstOrDefault(it => it.IsTreeKey); - List result = new List() { }; - var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; - var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); - var parentPropertyName = ParentInfo.DbColumnName; - var tableName = this.QueryBuilder.GetTableNameString; - if (this.QueryBuilder.IsSingle() == false) - { - if (this.QueryBuilder.JoinQueryInfos.Count > 0) - { - tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; - } - if (this.QueryBuilder.EasyJoinInfos.Count > 0) - { - tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; - } - } - var current = this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { - new ConditionalModel() - { - ConditionalType = ConditionalType.Equal, - CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, - FieldValue = primaryKeyValue + "", - FieldName = treeKey.DbColumnName - } }).First(); - if (current != null) - { - result.Add(current); - object parentId = ParentInfo.PropertyInfo.GetValue(current, null); - int i = 0; - while (parentId != null && this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { - new ConditionalModel() - { - ConditionalType = ConditionalType.Equal, - CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, - FieldValue = parentId + "", - FieldName = treeKey.DbColumnName - } }).Any()) - { - Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0")); - var parent = this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { - new ConditionalModel() - { - ConditionalType = ConditionalType.Equal, - CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, - FieldValue = parentId + "", - FieldName = treeKey.DbColumnName - } }).First(); - result.Add(parent); - parentId = ParentInfo.PropertyInfo.GetValue(parent, null); - ++i; - } - } - return result; - } - - public async Task> ToParentListAsync(Expression> parentIdExpression, object primaryKeyValue) - { - List result = new List() { }; - var entity = this.Context.EntityMaintenance.GetEntityInfo(); - var isTreeKey = entity.Columns.Any(it => it.IsTreeKey); - if (isTreeKey) - { - return await _ToParentListByTreeKeyAsync(parentIdExpression, primaryKeyValue); - } - Check.Exception(entity.Columns.Where(it => it.IsPrimarykey).Count() == 0, "No Primary key"); - var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; - var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); - var parentPropertyName = ParentInfo.DbColumnName; - var tableName = this.QueryBuilder.GetTableNameString; - if (this.QueryBuilder.IsSingle() == false) - { - if (this.QueryBuilder.JoinQueryInfos.Count > 0) - { - tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; - } - if (this.QueryBuilder.EasyJoinInfos.Count > 0) - { - tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; - } - } - var current =await this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingleAsync(primaryKeyValue); - if (current != null) - { - result.Add(current); - object parentId = ParentInfo.PropertyInfo.GetValue(current, null); - int i = 0; - while (parentId != null &&await this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).In(parentId).AnyAsync()) - { - Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0")); - var parent =await this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingleAsync(parentId); - result.Add(parent); - parentId = ParentInfo.PropertyInfo.GetValue(parent, null); - ++i; - } - } - return result; - } - private async Task> _ToParentListByTreeKeyAsync(Expression> parentIdExpression, object primaryKeyValue) - { - var entity = this.Context.EntityMaintenance.GetEntityInfo(); - var treeKey = entity.Columns.FirstOrDefault(it => it.IsTreeKey); - List result = new List() { }; - var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name; - var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName); - var parentPropertyName = ParentInfo.DbColumnName; - var tableName = this.QueryBuilder.GetTableNameString; - if (this.QueryBuilder.IsSingle() == false) - { - if (this.QueryBuilder.JoinQueryInfos.Count > 0) - { - tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; - } - if (this.QueryBuilder.EasyJoinInfos.Count > 0) - { - tableName = this.QueryBuilder.JoinQueryInfos.First().TableName; - } - } - var current = await this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { - new ConditionalModel() - { - ConditionalType = ConditionalType.Equal, - CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, - FieldValue = primaryKeyValue + "", - FieldName = treeKey.DbColumnName - } }).FirstAsync(); - if (current != null) - { - result.Add(current); - object parentId = ParentInfo.PropertyInfo.GetValue(current, null); - int i = 0; - while (parentId != null && await this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { - new ConditionalModel() - { - ConditionalType = ConditionalType.Equal, - CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, - FieldValue = parentId + "", - FieldName = treeKey.DbColumnName - } }).AnyAsync()) - { - Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限(100),检查最顶层的ParentId是否是null或者0")); - var parent = await this.Context.Queryable().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List() { - new ConditionalModel() - { - ConditionalType = ConditionalType.Equal, - CSharpTypeName = treeKey.PropertyInfo.PropertyType.Name, - FieldValue = parentId + "", - FieldName = treeKey.DbColumnName - } }).FirstAsync(); - result.Add(parent); - parentId = ParentInfo.PropertyInfo.GetValue(parent, null); - ++i; - } - } - return result; - } - - public List ToTree(Expression>> childListExpression, Expression> parentIdExpression, object rootValue) - { - var entity = this.Context.EntityMaintenance.GetEntityInfo(); - var pk = GetTreeKey(entity); - var list = this.ToList(); - return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue); - } - - public async Task> ToTreeAsync(Expression>> childListExpression, Expression> parentIdExpression, object rootValue) - { - var entity = this.Context.EntityMaintenance.GetEntityInfo(); - var pk = GetTreeKey(entity); ; - var list =await this.ToListAsync(); - return GetTreeRoot(childListExpression, parentIdExpression, pk, list,rootValue); - } - - public virtual DataTable ToDataTable() - { - QueryBuilder.ResultType = typeof(SugarCacheDataTable); - InitMapping(); - var sqlObj = this.ToSql(); - RestoreMapping(); - DataTable result = null; - bool isChangeQueryableMasterSlave = GetIsMasterQuery(); - bool isChangeQueryableSlave = GetIsSlaveQuery(); - if (IsCache) - { - var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; - result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => { return this.Db.GetDataTable(sqlObj.Key, sqlObj.Value.ToArray()); }, CacheTime, this.Context,CacheKey); - } - else - { - result = this.Db.GetDataTable(sqlObj.Key, sqlObj.Value.ToArray()); - } - RestChangeMasterQuery(isChangeQueryableMasterSlave); - RestChangeSlaveQuery(isChangeQueryableSlave); - return result; - } - public virtual DataTable ToDataTablePage(int pageIndex, int pageSize) - { - if (pageIndex == 0) - pageIndex = 1; - if (QueryBuilder.PartitionByValue.HasValue()) - { - QueryBuilder.ExternalPageIndex = pageIndex; - QueryBuilder.ExternalPageSize = pageSize; - } - else - { - QueryBuilder.Skip = (pageIndex - 1) * pageSize; - QueryBuilder.Take = pageSize; - } - return ToDataTable(); - } - public virtual DataTable ToDataTablePage(int pageIndex, int pageSize, ref int totalNumber) - { - _RestoreMapping = false; - totalNumber = this.Clone().Count(); - _RestoreMapping = true; - var result = this.Clone().ToDataTablePage(pageIndex, pageSize); - return result; - } - public virtual DataTable ToDataTablePage(int pageIndex, int pageSize, ref int totalNumber, ref int totalPage) - { - var result = ToDataTablePage(pageIndex, pageSize, ref totalNumber); - totalPage = (totalNumber + pageSize - 1) / pageSize; - return result; - } - - public Dictionary ToDictionary(Expression> key, Expression> value) - { - this.QueryBuilder.ResultType = typeof(SugarCacheDictionary); - var keyName = QueryBuilder.GetExpressionValue(key, ResolveExpressType.FieldSingle).GetResultString(); - var valueName = QueryBuilder.GetExpressionValue(value, ResolveExpressType.FieldSingle).GetResultString(); - if (this.QueryBuilder.IsSingle() == false) - { - keyName = this.QueryBuilder.TableShortName+ "." + keyName; - valueName = this.QueryBuilder.TableShortName + "." + valueName; - } - var result = this.Select>(keyName + "," + valueName).ToList().ToDictionary(it => it.Key.ObjToString(), it => it.Value); - return result; - } - public async Task> ToDictionaryAsync(Expression> key, Expression> value) - { - this.QueryBuilder.ResultType = typeof(SugarCacheDictionary); - var keyName = QueryBuilder.GetExpressionValue(key, ResolveExpressType.FieldSingle).GetResultString(); - var valueName = QueryBuilder.GetExpressionValue(value, ResolveExpressType.FieldSingle).GetResultString(); - var list = await this.Select>(keyName + "," + valueName).ToListAsync(); - var result =list.ToDictionary(it => it.Key.ObjToString(), it => it.Value); - return result; - } - public List> ToDictionaryList() - { - var list = this.ToList(); - if (list == null) - return null; - else - return this.Context.Utilities.DeserializeObject>>(this.Context.Utilities.SerializeObject(list)); - } - public async Task>> ToDictionaryListAsync() - { - var list =await this.ToListAsync(); - if (list == null) - return null; - else - return this.Context.Utilities.DeserializeObject>>(this.Context.Utilities.SerializeObject(list)); - } - - public virtual List ToList() - { - InitMapping(); - return _ToList(); - } - public List SetContext(Expression> thisFiled, Expression> mappingFiled, ParameterT parameter) - { - if (parameter == null) - { - return new List(); - } - List result = new List(); - var entity = this.Context.EntityMaintenance.GetEntityInfo(); - var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext; - var list = queryableContext.list; - var pkName = ""; - if ((mappingFiled as LambdaExpression).Body is UnaryExpression) - { - pkName = (((mappingFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name; - } - else - { - pkName = ((mappingFiled as LambdaExpression).Body as MemberExpression).Member.Name; - } - var key = thisFiled.ToString()+mappingFiled.ToString() +typeof(ParameterT).FullName + typeof(T).FullName; - var ids = list.Where(it=>it!=null).Select(it => it.GetType().GetProperty(pkName).GetValue(it)).Distinct().ToArray(); - if (queryableContext.TempChildLists == null) - queryableContext.TempChildLists = new Dictionary(); - if (list != null && queryableContext.TempChildLists.ContainsKey(key)) - { - result = (List)queryableContext.TempChildLists[key]; - } - else - { - if (queryableContext.TempChildLists == null) - queryableContext.TempChildLists = new Dictionary(); - this.Context.Utilities.PageEach(ids, 200, pageIds => - { - result.AddRange(this.Clone().In(thisFiled, pageIds).ToList()); - }); - queryableContext.TempChildLists[key]= result; - } - var name = ""; - if((thisFiled as LambdaExpression).Body is UnaryExpression) - { - name = (((thisFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name; - } - else - { - name = ((thisFiled as LambdaExpression).Body as MemberExpression).Member.Name; - } - var pkValue = parameter.GetType().GetProperty(pkName).GetValue(parameter); - result = result.Where(it => it.GetType().GetProperty(name).GetValue(it).ObjToString() == pkValue.ObjToString()).ToList(); - return result; - } - public List SetContext(Expression> thisFiled1, Expression> mappingFiled1, - Expression> thisFiled2, Expression> mappingFiled2, - ParameterT parameter) - { - if (parameter == null) - { - return new List(); - } - var rightEntity = this.Context.EntityMaintenance.GetEntityInfo(); - var leftEntity = this.Context.EntityMaintenance.GetEntityInfo(); - List result = new List(); - var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext; - var list = queryableContext.list; - var key = thisFiled1.ToString() + mappingFiled1.ToString()+ - thisFiled2.ToString() + mappingFiled2.ToString()+ - typeof(ParameterT).FullName + typeof(T).FullName; - MappingFieldsHelper fieldsHelper = new MappingFieldsHelper(); - var mappings = new List() { - new MappingFieldsExpression(){ - LeftColumnExpression=thisFiled1, - LeftEntityColumn=leftEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(thisFiled1)), - RightColumnExpression=mappingFiled1, - RightEntityColumn=rightEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(mappingFiled1)) - }, - new MappingFieldsExpression(){ - LeftColumnExpression=thisFiled2, - LeftEntityColumn=leftEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(thisFiled2)), - RightColumnExpression=mappingFiled2, - RightEntityColumn=rightEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(mappingFiled2)) - } - }; - var conditionals=fieldsHelper.GetMppingSql(list.Cast().ToList(), mappings); - if (queryableContext.TempChildLists == null) - queryableContext.TempChildLists = new Dictionary(); - if (list != null && queryableContext.TempChildLists.ContainsKey(key)) - { - result = (List)queryableContext.TempChildLists[key]; - } - else - { - result = this.Clone().Where(conditionals,true).ToList(); - queryableContext.TempChildLists[key] = result; - } - List listObj = result.Select(it => (object)it).ToList(); - object obj = (object)parameter; - var newResult = fieldsHelper.GetSetList(obj, listObj, mappings).Select(it=>(T)it ).ToList(); - return newResult; - } - public async Task> SetContextAsync(Expression> thisFiled, Expression> mappingFiled, ParameterT parameter) - { - List result = new List(); - var entity = this.Context.EntityMaintenance.GetEntityInfo(); - var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext; - var list = queryableContext.list; - var pkName = ""; - if ((mappingFiled as LambdaExpression).Body is UnaryExpression) - { - pkName = (((mappingFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name; - } - else - { - pkName = ((mappingFiled as LambdaExpression).Body as MemberExpression).Member.Name; - } - var key = thisFiled.ToString()+ mappingFiled.ToString() + typeof(ParameterT).FullName + typeof(T).FullName; - var ids = list.Select(it => it.GetType().GetProperty(pkName).GetValue(it)).ToArray(); - if (queryableContext.TempChildLists == null) - queryableContext.TempChildLists = new Dictionary(); - if (list != null && queryableContext.TempChildLists.ContainsKey(key)) - { - result = (List)queryableContext.TempChildLists[key]; - } - else - { - if (queryableContext.TempChildLists == null) - queryableContext.TempChildLists = new Dictionary(); - await this.Context.Utilities.PageEachAsync(ids, 200, async pageIds => - { - result.AddRange(await this.Clone().In(thisFiled, pageIds).ToListAsync()); - }); - queryableContext.TempChildLists[key] = result; - } - var name = ""; - if ((thisFiled as LambdaExpression).Body is UnaryExpression) - { - name = (((thisFiled as LambdaExpression).Body as UnaryExpression).Operand as MemberExpression).Member.Name; - } - else - { - name = ((thisFiled as LambdaExpression).Body as MemberExpression).Member.Name; - } - var pkValue = parameter.GetType().GetProperty(pkName).GetValue(parameter); - result = result.Where(it => it.GetType().GetProperty(name).GetValue(it).ObjToString() == pkValue.ObjToString()).ToList(); - return result; - } - public async Task> SetContextAsync(Expression> thisFiled1, Expression> mappingFiled1, - Expression> thisFiled2, Expression> mappingFiled2, - ParameterT parameter) - { - if (parameter == null) - { - return new List(); - } - var rightEntity = this.Context.EntityMaintenance.GetEntityInfo(); - var leftEntity = this.Context.EntityMaintenance.GetEntityInfo(); - List result = new List(); - var queryableContext = this.Context.TempItems["Queryable_To_Context"] as MapperContext; - var list = queryableContext.list; - var key = thisFiled1.ToString() + mappingFiled1.ToString() + - thisFiled2.ToString() + mappingFiled2.ToString() + - typeof(ParameterT).FullName + typeof(T).FullName; - MappingFieldsHelper fieldsHelper = new MappingFieldsHelper(); - var mappings = new List() { - new MappingFieldsExpression(){ - LeftColumnExpression=thisFiled1, - LeftEntityColumn=leftEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(thisFiled1)), - RightColumnExpression=mappingFiled1, - RightEntityColumn=rightEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(mappingFiled1)) - }, - new MappingFieldsExpression(){ - LeftColumnExpression=thisFiled2, - LeftEntityColumn=leftEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(thisFiled2)), - RightColumnExpression=mappingFiled2, - RightEntityColumn=rightEntity.Columns.First(it=>it.PropertyName==ExpressionTool.GetMemberName(mappingFiled2)) - } - }; - var conditionals = fieldsHelper.GetMppingSql(list.Cast().ToList(), mappings); - if (queryableContext.TempChildLists == null) - queryableContext.TempChildLists = new Dictionary(); - if (list != null && queryableContext.TempChildLists.ContainsKey(key)) - { - result = (List)queryableContext.TempChildLists[key]; - } - else - { - result =await this.Clone().Where(conditionals, true).ToListAsync(); - queryableContext.TempChildLists[key] = result; - } - List listObj = result.Select(it => (object)it).ToList(); - object obj = (object)parameter; - var newResult = fieldsHelper.GetSetList(obj, listObj, mappings).Select(it => (T)it).ToList(); - return newResult; - } - public virtual void ForEach(Action action, int singleMaxReads = 300,System.Threading.CancellationTokenSource cancellationTokenSource = null) - { - Check.Exception(this.QueryBuilder.Skip > 0 || this.QueryBuilder.Take > 0, ErrorMessage.GetThrowMessage("no support Skip take, use PageForEach", "不支持Skip Take,请使用 Queryale.PageForEach")); - var totalNumber = 0; - var totalPage = 1; - for (int i = 1; i <= totalPage; i++) - { - if (cancellationTokenSource?.IsCancellationRequested == true) return; - var queryable = this.Clone(); - var page = - totalPage==1? - queryable.ToPageList(i, singleMaxReads, ref totalNumber, ref totalPage): - queryable.ToPageList(i, singleMaxReads); - foreach (var item in page) - { - if (cancellationTokenSource?.IsCancellationRequested == true) return; - action.Invoke(item); - } - } - } - public virtual async Task ForEachAsync(Action action, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null) - { - Check.Exception(this.QueryBuilder.Skip > 0 || this.QueryBuilder.Take > 0, ErrorMessage.GetThrowMessage("no support Skip take, use PageForEach", "不支持Skip Take,请使用 Queryale.PageForEach")); - RefAsync totalNumber = 0; - RefAsync totalPage = 1; - for (int i = 1; i <= totalPage; i++) - { - if (cancellationTokenSource?.IsCancellationRequested == true) return; - var queryable = this.Clone(); - var page = - totalPage == 1 ? - await queryable.ToPageListAsync(i, singleMaxReads, totalNumber, totalPage) : - await queryable.ToPageListAsync(i, singleMaxReads); - foreach (var item in page) - { - if (cancellationTokenSource?.IsCancellationRequested == true) return; - action.Invoke(item); - } - } - } - public virtual void ForEachByPage(Action action, int pageIndex, int pageSize, ref int totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null) - { - int count = this.Clone().Count(); - if (count > 0) - { - if (pageSize > singleMaxReads && count - ((pageIndex - 1) * pageSize) > singleMaxReads) - { - Int32 Skip = (pageIndex - 1) * pageSize; - Int32 NowCount = count - Skip; - Int32 number = 0; - if (NowCount > pageSize) NowCount = pageSize; - while (NowCount > 0) - { - if (cancellationTokenSource?.IsCancellationRequested == true) return; - if (number + singleMaxReads > pageSize) singleMaxReads = NowCount; - foreach (var item in this.Clone().Skip(Skip).Take(singleMaxReads).ToList()) - { - if (cancellationTokenSource?.IsCancellationRequested == true) return; - action.Invoke(item); - } - NowCount -= singleMaxReads; - Skip += singleMaxReads; - number += singleMaxReads; - } - } - else - { - if (cancellationTokenSource?.IsCancellationRequested == true) return; - foreach (var item in this.Clone().ToPageList(pageIndex, pageSize)) - { - if (cancellationTokenSource?.IsCancellationRequested == true) return; - action.Invoke(item); - } - } - } - totalNumber = count; - } - public virtual async Task ForEachByPageAsync(Action action, int pageIndex, int pageSize,RefAsync totalNumber, int singleMaxReads = 300, System.Threading.CancellationTokenSource cancellationTokenSource = null) - { - int count = this.Clone().Count(); - if (count > 0) - { - if (pageSize > singleMaxReads && count - ((pageIndex - 1) * pageSize) > singleMaxReads) - { - Int32 Skip = (pageIndex - 1) * pageSize; - Int32 NowCount = count - Skip; - Int32 number = 0; - if (NowCount > pageSize) NowCount = pageSize; - while (NowCount > 0) - { - if (cancellationTokenSource?.IsCancellationRequested == true) return; - if (number + singleMaxReads > pageSize) singleMaxReads = NowCount; - foreach (var item in await this.Clone().Skip(Skip).Take(singleMaxReads).ToListAsync()) - { - if (cancellationTokenSource?.IsCancellationRequested == true) return; - action.Invoke(item); - } - NowCount -= singleMaxReads; - Skip += singleMaxReads; - number += singleMaxReads; - } - } - else - { - if (cancellationTokenSource?.IsCancellationRequested == true) return; - foreach (var item in this.Clone().ToPageList(pageIndex, pageSize)) - { - if (cancellationTokenSource?.IsCancellationRequested == true) return; - action.Invoke(item); - } - } - } - totalNumber = count; - } - - public List ToOffsetPage(int pageIndex, int pageSize) - { - if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) - { - this.QueryBuilder.Offset = "true"; - return this.ToPageList(pageIndex, pageSize); - } - else - { - _ToOffsetPage(pageIndex, pageSize); - return this.ToList(); - } - } - public List ToOffsetPage(int pageIndex, int pageSize, ref int totalNumber) - { - if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) - { - this.QueryBuilder.Offset = "true"; - return this.ToPageList(pageIndex, pageSize, ref totalNumber); - } - else - { - totalNumber = this.Clone().Count(); - _ToOffsetPage(pageIndex, pageSize); - return this.Clone().ToList(); - } - } - public Task> ToOffsetPageAsync(int pageIndex, int pageSize) - { - if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) - { - this.QueryBuilder.Offset = "true"; - return this.ToPageListAsync(pageIndex, pageSize); - } - else - { - _ToOffsetPage(pageIndex, pageSize); - return this.ToListAsync(); - } - } - public async Task> ToOffsetPageAsync(int pageIndex, int pageSize, RefAsync totalNumber) - { - if (this.Context.CurrentConnectionConfig.DbType != DbType.SqlServer) - { - this.QueryBuilder.Offset = "true"; - return await this.ToPageListAsync(pageIndex, pageSize, totalNumber); - } - else - { - totalNumber.Value =await this.Clone().CountAsync(); - _ToOffsetPage(pageIndex, pageSize); - return await this.Clone().ToListAsync(); - } - } - public virtual List ToPageList(int pageIndex, int pageSize) - { - pageIndex = _PageList(pageIndex, pageSize); - return ToList(); - } - public virtual List ToPageList(int pageIndex, int pageSize, ref int totalNumber,Expression> expression) - { - if (this.QueryBuilder.Includes!=null&&this.QueryBuilder.Includes.Count > 0) - { - if (pageIndex == 0) - pageIndex = 1; - var list = this.Clone().Skip((pageIndex-1)*pageSize).Take(pageSize).ToList(expression); - var countQueryable = this.Clone(); - countQueryable.QueryBuilder.Includes = null; - totalNumber = countQueryable.Count(); - return list; - } - else - { - var list = this.Select(expression).ToPageList(pageIndex, pageSize, ref totalNumber).ToList(); - return list; - } - } - public virtual List ToPageList(int pageIndex, int pageSize, ref int totalNumber) - { - var oldMapping = this.Context.MappingTables; - var countQueryable = this.Clone(); - if (countQueryable.QueryBuilder.Offset == "true") - { - countQueryable.QueryBuilder.Offset = null; - } - totalNumber = countQueryable.Count(); - this.Context.MappingTables = oldMapping; - return this.Clone().ToPageList(pageIndex, pageSize); - } - public virtual List ToPageList(int pageIndex, int pageSize, ref int totalNumber, ref int totalPage) - { - var result = ToPageList(pageIndex, pageSize, ref totalNumber); - totalPage = (totalNumber + pageSize - 1) / pageSize; - return result; - } - public virtual string ToSqlString() - { - var sqlObj = this.Clone().ToSql(); - var result = sqlObj.Key; - if (result == null) return null; - result = UtilMethods.GetSqlString(this.Context.CurrentConnectionConfig,sqlObj); - return result; - } - - - public virtual KeyValuePair> ToSql() - { - if (!QueryBuilder.IsClone) - { - var newQueryable = this.Clone(); - newQueryable.QueryBuilder.IsClone = true; - return newQueryable.ToSql(); - } - else - { - return _ToSql(); - } - } - public string ToClassString(string className) - { - List columns = new List(); - var properties = typeof(T).GetProperties(); - foreach (var item in properties) - { - columns.Add(new DbColumnInfo() - { - DbColumnName = item.Name, - PropertyName = UtilMethods.GetUnderType(item.PropertyType).Name, - PropertyType = UtilMethods.GetUnderType(item.PropertyType) - }); - } - var result = ((this.Context.DbFirst) as DbFirstProvider).GetClassString(columns, ref className); - return result; - } - #region Async methods - public virtual async Task InSingleAsync(object pkValue) - { - Check.Exception(this.QueryBuilder.SelectValue.HasValue(), "'InSingle' and' Select' can't be used together,You can use .Select(it=>...).Single(it.id==1)"); - var list =await In(pkValue).ToListAsync(); - if (list == null) return default(T); - else return list.SingleOrDefault(); - } - public async Task SingleAsync() - { - if (QueryBuilder.OrderByValue.IsNullOrEmpty()) - { - QueryBuilder.OrderByValue = QueryBuilder.DefaultOrderByTemplate; - } - var oldSkip = QueryBuilder.Skip; - var oldTake = QueryBuilder.Take; - var oldOrderBy = QueryBuilder.OrderByValue; - QueryBuilder.Skip = null; - QueryBuilder.Take = null; - QueryBuilder.OrderByValue = null; - var result =await this.ToListAsync(); - QueryBuilder.Skip = oldSkip; - QueryBuilder.Take = oldTake; - QueryBuilder.OrderByValue = oldOrderBy; - if (result == null || result.Count == 0) - { - return default(T); - } - else if (result.Count == 2) - { - Check.Exception(true, ErrorMessage.GetThrowMessage(".Single() result must not exceed one . You can use.First()", "使用single查询结果集不能大于1,适合主键查询,如果大于1你可以使用Queryable.First")); - return default(T); - } - else - { - return result.SingleOrDefault(); - } - } - - public async Task SingleAsync(Expression> expression) - { - _Where(expression); - var result =await SingleAsync(); - this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); - return result; - } - - public async Task FirstAsync() - { - if (QueryBuilder.OrderByValue.IsNullOrEmpty()) - { - QueryBuilder.OrderByValue = QueryBuilder.DefaultOrderByTemplate; - } - if (QueryBuilder.Skip.HasValue) - { - QueryBuilder.Take = 1; - var list = await this.ToListAsync(); - return list.FirstOrDefault(); - } - else - { - QueryBuilder.Skip = 0; - QueryBuilder.Take = 1; - var result =await this.ToListAsync(); - if (result.HasValue()) - return result.FirstOrDefault(); - else - return default(T); - } - } - - public async Task FirstAsync(Expression> expression) - { - _Where(expression); - var result = await FirstAsync(); - this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); - return result; - } - - public async Task AnyAsync(Expression> expression) - { - _Where(expression); - var result =await AnyAsync(); - this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); - return result; - } - - public async Task AnyAsync() - { - return await this.CountAsync() > 0; - } - - public async Task CountAsync() - { - if (this.QueryBuilder.Skip == null && - this.QueryBuilder.Take == null && - this.QueryBuilder.OrderByValue == null && - this.QueryBuilder.PartitionByValue == null && - this.QueryBuilder.SelectValue == null && - this.QueryBuilder.Includes == null&& - this.QueryBuilder.IsDistinct==false) - { - var list = await this.Clone().Select(" COUNT(1) ").ToListAsync(); - return list.FirstOrDefault(); - } - MappingTableList expMapping; - int result; - _CountBegin(out expMapping, out result); - if (IsCache) - { - var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; - result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => { return GetCount(); }, CacheTime, this.Context,CacheKey); - } - else - { - result =await GetCountAsync(); - } - _CountEnd(expMapping); - return result; - } - public async Task CountAsync(Expression> expression) - { - _Where(expression); - var result =await CountAsync(); - this.QueryBuilder.WhereInfos.Remove(this.QueryBuilder.WhereInfos.Last()); - return result; - } - public async Task MaxAsync(string maxField) - { - this.Select(string.Format(QueryBuilder.MaxTemplate, maxField)); - var list = await this._ToListAsync(); - var result =list.SingleOrDefault(); - return result; - } - - public Task MaxAsync(Expression> expression) - { - return _MaxAsync(expression); - } - - public async Task MinAsync(string minField) - { - this.Select(string.Format(QueryBuilder.MinTemplate, minField)); - var list = await this._ToListAsync(); - var result = list.SingleOrDefault(); - return result; - } - - public Task MinAsync(Expression> expression) - { - return _MinAsync(expression); - } - - public async Task SumAsync(string sumField) - { - this.Select(string.Format(QueryBuilder.SumTemplate, sumField)); - var list = await this._ToListAsync(); - var result = list.SingleOrDefault(); - return result; - } - - public Task SumAsync(Expression> expression) - { - return _SumAsync(expression); - } - - public async Task AvgAsync(string avgField) - { - this.Select(string.Format(QueryBuilder.AvgTemplate, avgField)); - var list = await this._ToListAsync(); - var result = list.SingleOrDefault(); - return result; - } - - public Task AvgAsync(Expression> expression) - { - return _AvgAsync(expression); - } - - public Task> ToListAsync() - { - InitMapping(); - return _ToListAsync(); - } - public Task> ToPageListAsync(int pageIndex, int pageSize) - { - pageIndex = _PageList(pageIndex, pageSize); - return ToListAsync(); - } - public async virtual Task> ToPageListAsync(int pageIndex, int pageSize, RefAsync totalNumber, Expression> expression) - { - if (this.QueryBuilder.Includes!=null&&this.QueryBuilder.Includes.Count > 0) - { - if (pageIndex == 0) - pageIndex = 1; - var list =await this.Clone().Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(expression); - var countQueryable = this.Clone(); - countQueryable.QueryBuilder.Includes = null; - totalNumber.Value =await countQueryable.CountAsync(); - return list; - } - else - { - var list = await this.Select(expression).ToPageListAsync(pageIndex, pageSize, totalNumber) ; - return list; - } - } - public async Task> ToPageListAsync(int pageIndex, int pageSize, RefAsync totalNumber) - { - var oldMapping = this.Context.MappingTables; - var countQueryable = this.Clone(); - if (countQueryable.QueryBuilder.Offset == "true") - { - countQueryable.QueryBuilder.Offset = null; - } - totalNumber.Value = await countQueryable.CountAsync(); - this.Context.MappingTables = oldMapping; - return await this.Clone().ToPageListAsync(pageIndex, pageSize); - } - public async Task> ToPageListAsync(int pageNumber, int pageSize, RefAsync totalNumber, RefAsync totalPage) - { - var result =await ToPageListAsync(pageNumber, pageSize, totalNumber); - totalPage.Value = (totalNumber.Value + pageSize - 1) / pageSize; - return result; - } - public async Task ToJsonAsync() - { - if (IsCache) - { - var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; - var result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => - { - return this.Context.Utilities.SerializeObject(this.ToList(), typeof(T)); - }, CacheTime, this.Context,CacheKey); - return result; - } - else - { - return this.Context.Utilities.SerializeObject(await this.ToListAsync(), typeof(T)); - } - } - public async Task ToJsonPageAsync(int pageIndex, int pageSize) - { - return this.Context.Utilities.SerializeObject(await this.ToPageListAsync(pageIndex, pageSize), typeof(T)); - } - public async Task ToJsonPageAsync(int pageIndex, int pageSize, RefAsync totalNumber) - { - var oldMapping = this.Context.MappingTables; - totalNumber.Value = await this.Clone().CountAsync(); - this.Context.MappingTables = oldMapping; - return await this.Clone().ToJsonPageAsync(pageIndex, pageSize); - } - public async Task ToDataTableAsync() - { - QueryBuilder.ResultType = typeof(SugarCacheDataTable); - InitMapping(); - var sqlObj = this._ToSql(); - RestoreMapping(); - DataTable result = null; - if (IsCache) - { - var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; - result = CacheSchemeMain.GetOrCreate(cacheService, this.QueryBuilder, () => { return this.Db.GetDataTable(sqlObj.Key, sqlObj.Value.ToArray()); }, CacheTime, this.Context,CacheKey); - } - else - { - result = await this.Db.GetDataTableAsync(sqlObj.Key, sqlObj.Value.ToArray()); - } - return result; - } - public Task ToDataTablePageAsync(int pageIndex, int pageSize) - { - pageIndex = _PageList(pageIndex, pageSize); - return ToDataTableAsync(); - } - public async Task ToDataTablePageAsync(int pageIndex, int pageSize, RefAsync totalNumber) - { - var oldMapping = this.Context.MappingTables; - totalNumber.Value = await this.Clone().CountAsync(); - this.Context.MappingTables = oldMapping; - return await this.Clone().ToDataTablePageAsync(pageIndex, pageSize); - } - - #endregion } - } diff --git a/Src/Asp.Net/SqlSugar/SqlSugar.csproj b/Src/Asp.Net/SqlSugar/SqlSugar.csproj index 07d00ed83..0a9f8fe1e 100644 --- a/Src/Asp.Net/SqlSugar/SqlSugar.csproj +++ b/Src/Asp.Net/SqlSugar/SqlSugar.csproj @@ -114,6 +114,8 @@ + +