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; using System.Collections.ObjectModel; using NetTaste; using Newtonsoft.Json.Linq; using System.Xml.Linq; using System.Runtime.CompilerServices; namespace SqlSugar { public partial class QueryableProvider : QueryableAccessory, ISugarQueryable { #region Tree 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 List _ToParentListByTreeKey(Expression> parentIdExpression, object primaryKeyValue, Expression> parentWhereExpression) { 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).WhereIF(parentWhereExpression != default, parentWhereExpression).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).WhereIF(parentWhereExpression != default, parentWhereExpression).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).WhereIF(parentWhereExpression != default, parentWhereExpression).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; } private async Task> _ToParentListByTreeKeyAsync(Expression> parentIdExpression, object primaryKeyValue, Expression> parentWhereExpression) { 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).WhereIF(parentWhereExpression!=default, parentWhereExpression).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).WhereIF(parentWhereExpression!=default, parentWhereExpression).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).WhereIF(parentWhereExpression!=default, parentWhereExpression).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; } private List GetChildList(Expression> parentIdExpression, string pkName, List list, object rootValue, bool isContainOneself) { var exp = (parentIdExpression as LambdaExpression).Body; if (exp is UnaryExpression) { exp = (exp as UnaryExpression).Operand; } var parentIdName = (exp as MemberExpression).Member.Name; var result = BuildChildList(list, pkName, parentIdName, rootValue, isContainOneself); return result; } private static List BuildChildList(List list, string idName, string pIdName, object rootValue, bool isContainOneself) { var type = typeof(T); var idProp = type.GetProperty(idName); var pIdProp = type.GetProperty(pIdName); var kvpList = list.ToDictionary(x => x, v => idProp.GetValue(v).ObjToString()); var groupKv = list.GroupBy(x => pIdProp.GetValue(x).ObjToString()).ToDictionary(k => k.Key, v => v.ToList()); Func> fc = null; fc = (rootVal) => { var finalList = new List(); if (groupKv.TryGetValue(rootVal, out var nextChildList)) { finalList.AddRange(nextChildList); foreach (var child in nextChildList) { finalList.AddRange(fc(kvpList[child])); } } return finalList; }; var result = fc(rootValue.ObjToString()); if (isContainOneself) { var root = kvpList.FirstOrDefault(x => x.Value == rootValue.ObjToString()).Key; if (root != null) { result.Insert(0, root); } } return result; } private List GetPrentIds(List list, object id, EntityColumnInfo pkName, EntityColumnInfo parentName) { var currentId = id; List result = new List(); result.Add(id); while (list.Any(it => pkName.PropertyInfo.GetValue(it).ObjToString()==currentId.ObjToString())) { var data = list.First(it => pkName.PropertyInfo.GetValue(it).ObjToString() == currentId.ObjToString()); currentId = parentName.PropertyInfo.GetValue(data); result.Add(currentId); } return result; } private List TreeAndFilterIds(Expression>> childListExpression, Expression> parentIdExpression, object rootValue, object[] childIds, ref List list) { var entity = this.Context.EntityMaintenance.GetEntityInfo(); var pk = GetTreeKey(entity); var pkColumn = entity.Columns.FirstOrDefault(z => z.PropertyName == pk); var newIds = new List(); string parentIdName = GetParentName(parentIdExpression); var parentColumn = entity.Columns.FirstOrDefault(z => z.PropertyName == parentIdName); foreach (var id in childIds) { newIds.AddRange(GetPrentIds(list, id, pkColumn, parentColumn)); } list = list.Where(z => newIds.Any(it => it.ObjToString()==pkColumn.PropertyInfo.GetValue(z).ObjToString())).ToList(); return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue); } private List TreeAndFilterIds(Expression>> childListExpression, Expression> parentIdExpression, Expression> primaryKeyExpresion, object rootValue, object[] childIds, ref List list) { var entity = this.Context.EntityMaintenance.GetEntityInfo(); var pk = ExpressionTool.GetMemberName(primaryKeyExpresion); var pkColumn = entity.Columns.FirstOrDefault(z => z.PropertyName == pk); var newIds = new List(); string parentIdName = GetParentName(parentIdExpression); var parentColumn = entity.Columns.FirstOrDefault(z => z.PropertyName == parentIdName); foreach (var id in childIds) { newIds.AddRange(GetPrentIds(list, id, pkColumn, parentColumn)); } list = list.Where(z => newIds.Any(it => it.ObjToString() == pkColumn.PropertyInfo.GetValue(z).ObjToString())).ToList(); return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue); } internal List GetTreeRoot(Expression>> childListExpression, Expression> parentIdExpression, string pk, List list, object rootValue) { var childName = ((childListExpression as LambdaExpression).Body as MemberExpression).Member.Name; string parentIdName = GetParentName(parentIdExpression); return UtilMethods.BuildTree(this.Context,list, pk, parentIdName, childName, rootValue)?.ToList() ?? default; } private static string GetParentName(Expression> parentIdExpression) { var exp = (parentIdExpression as LambdaExpression).Body; if (exp is UnaryExpression) { exp = (exp as UnaryExpression).Operand; } var parentIdName = (exp as MemberExpression).Member.Name; return parentIdName; } public List GetTreeChildList(List alllist, object pkValue, string pkName, string childName, string parentIdName) { var result = alllist.Where(it => { var value = it.GetType().GetProperty(parentIdName).GetValue(it); return value.ObjToString() == pkValue.ObjToString(); }).ToList(); if (result != null && result.Count > 0) { foreach (var item in result) { var itemPkValue = item.GetType().GetProperty(pkName).GetValue(item); item.GetType().GetProperty(childName).SetValue(item, GetTreeChildList(alllist, itemPkValue, pkName, childName, parentIdName)); } } return result; } private static string GetTreeKey(EntityInfo entity) { Check.Exception(entity.Columns.Where(it => it.IsPrimarykey || it.IsTreeKey).Count() == 0, "need IsPrimary=true Or IsTreeKey=true"); string pk = entity.Columns.Where(it => it.IsTreeKey).FirstOrDefault()?.PropertyName; if (pk == null) pk = entity.Columns.Where(it => it.IsPrimarykey).FirstOrDefault()?.PropertyName; return pk; } #endregion #region Count protected int GetCount() { var sql = string.Empty; ToSqlBefore(); sql = QueryBuilder.ToSqlString(); sql = QueryBuilder.ToCountSql(sql); var result = Context.Ado.GetInt(sql, QueryBuilder.Parameters.ToArray()); return result; } protected async Task GetCountAsync() { var sql = string.Empty; ToSqlBefore(); sql = QueryBuilder.ToSqlString(); sql = QueryBuilder.ToCountSql(sql); var result = Convert.ToInt32(await Context.Ado.GetScalarAsync(sql, QueryBuilder.Parameters.ToArray())); return result; } private void _CountEnd(MappingTableList expMapping) { RestoreMapping(); QueryBuilder.IsCount = false; if (expMapping.Count > 0) { if (this.QueryableMappingTableList == null) { this.QueryableMappingTableList = new MappingTableList(); } this.QueryableMappingTableList.Add(expMapping.First()); } } private void _CountBegin(out MappingTableList expMapping, out int result) { expMapping = new MappingTableList(); if (QueryBuilder.EntityName == "ExpandoObject" && this.Context.MappingTables.Any(it => it.EntityName == "ExpandoObject")) { expMapping.Add("ExpandoObject", this.Context.MappingTables.First(it => it.EntityName == "ExpandoObject").DbTableName); } InitMapping(); QueryBuilder.IsCount = true; result = 0; } #endregion #region Min Max Sum Gvg protected TResult _Min(Expression expression) { if (this.QueryBuilder.IsSqlQuery) { this.QueryBuilder.IsSqlQuery = false; } QueryBuilder.CheckExpression(expression, "Main"); var isSingle = QueryBuilder.IsSingle(); var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); var result = Min(lamResult.GetResultString()); QueryBuilder.SelectValue = null; return result; } protected async Task _MinAsync(Expression expression) { if (this.QueryBuilder.IsSqlQuery) { this.QueryBuilder.IsSqlQuery = false; } QueryBuilder.CheckExpression(expression, "Main"); var isSingle = QueryBuilder.IsSingle(); var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); var result = await MinAsync(lamResult.GetResultString()); QueryBuilder.SelectValue = null; return result; } protected TResult _Avg(Expression expression) { if (this.QueryBuilder.IsSqlQuery) { this.QueryBuilder.IsSqlQuery = false; } QueryBuilder.CheckExpression(expression, "Avg"); var isSingle = QueryBuilder.IsSingle(); var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); return Avg(lamResult.GetResultString()); } protected async Task _AvgAsync(Expression expression) { if (this.QueryBuilder.IsSqlQuery) { this.QueryBuilder.IsSqlQuery = false; } QueryBuilder.CheckExpression(expression, "Avg"); var isSingle = QueryBuilder.IsSingle(); var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); return await AvgAsync(lamResult.GetResultString()); } protected TResult _Max(Expression expression) { if (this.QueryBuilder.IsSqlQuery) { this.QueryBuilder.IsSqlQuery = false; } QueryBuilder.CheckExpression(expression, "Max"); var isSingle = QueryBuilder.IsSingle(); var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); var reslut = Max(lamResult.GetResultString()); QueryBuilder.SelectValue = null; return reslut; } protected async Task _MaxAsync(Expression expression) { if (this.QueryBuilder.IsSqlQuery) { this.QueryBuilder.IsSqlQuery = false; } QueryBuilder.CheckExpression(expression, "Max"); var isSingle = QueryBuilder.IsSingle(); var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); var reslut = await MaxAsync(lamResult.GetResultString()); QueryBuilder.SelectValue = null; return reslut; } protected TResult _Sum(Expression expression) { if (this.QueryBuilder.IsSqlQuery) { this.QueryBuilder.IsSqlQuery = false; } QueryBuilder.CheckExpression(expression, "Sum"); var isSingle = QueryBuilder.IsSingle(); var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); var reslut = Sum(lamResult.GetResultString()); QueryBuilder.SelectValue = null; return reslut; } protected async Task _SumAsync(Expression expression) { if (this.QueryBuilder.IsSqlQuery) { this.QueryBuilder.IsSqlQuery = false; } QueryBuilder.CheckExpression(expression, "Sum"); var isSingle = QueryBuilder.IsSingle(); var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); var reslut = await SumAsync(lamResult.GetResultString()); QueryBuilder.SelectValue = null; return reslut; } #endregion #region Master Slave private void RestChangeMasterQuery(bool isChangeQueryableMasterSlave) { if (isChangeQueryableMasterSlave) this.Context.Ado.IsDisableMasterSlaveSeparation = false; } private bool GetIsMasterQuery() { var isChangeQueryableMasterSlave = this.QueryBuilder.IsDisableMasterSlaveSeparation == true && this.Context.Ado.IsDisableMasterSlaveSeparation == false && this.Context.Ado.Transaction == null; if (isChangeQueryableMasterSlave) this.Context.Ado.IsDisableMasterSlaveSeparation = true; return isChangeQueryableMasterSlave; } private void RestChangeSlaveQuery(bool isChangeQueryableSlaveSlave) { if (isChangeQueryableSlaveSlave) this.Context.Ado.IsDisableMasterSlaveSeparation = true; } private bool GetIsSlaveQuery() { var isChangeQueryableMasterSlave = this.QueryBuilder.IsEnableMasterSlaveSeparation == true && this.Context.Ado.IsDisableMasterSlaveSeparation == true && this.Context.Ado.Transaction == null; if (isChangeQueryableMasterSlave) this.Context.Ado.IsDisableMasterSlaveSeparation = false; return isChangeQueryableMasterSlave; } #endregion #region Navigate internal bool IsAppendNavColumns() { return this.QueryBuilder.Includes.HasValue() && this.QueryBuilder.AppendNavInfo == null; } internal void SetAppendNavColumns(Expression expression) { var tResultType = expression.Type; var dic = ExpressionTool.GetNewExpressionItemList(expression); var navs = this.QueryBuilder.Includes; var navManages = navs.Cast>(); if (navManages.FirstOrDefault() == null) return; this.QueryBuilder.AppendNavInfo = new AppendNavInfo(); var navInfo = this.QueryBuilder.AppendNavInfo; var entityColumns = this.EntityInfo.Columns; var pkColumns = entityColumns.Where(it => it.IsPrimarykey); AddAppendProperties(navManages, navInfo, entityColumns, pkColumns); AddMappingNavProperties(dic, navInfo, entityColumns); } private void AddMappingNavProperties(Dictionary dic, AppendNavInfo navInfo, List entityColumns) { foreach (var item in dic) { var value = item.Value; var expressionTree = new ExpressionTreeVisitor().GetExpressions(value); var isSqlMethod = expressionTree.Any()&&ExpressionTool.GetMethodName(expressionTree.Last()).IsIn("Any", "Count"); if (expressionTree.Any()&&isSqlMethod==false) { var name = ExpressionTool.GetMemberName(expressionTree.First()); if (name != null && entityColumns.Any(it => it.Navigat != null && it.PropertyName == name)) { var mappingNavColumnInfo = new MappingNavColumnInfo() { ExpressionList = expressionTree, Name = name }; navInfo.MappingNavProperties.Add(item.Key, mappingNavColumnInfo); } else if (ExpressionTool.IsNavMember(this.Context,value)) { var mappingNavColumnInfo = new MappingNavColumnInfo() { ExpressionList = expressionTree, Name = name }; if (value is MemberExpression exp) { if (exp.Expression is MemberExpression expChild) { mappingNavColumnInfo.ParentName = expChild.Member.Name; } } navInfo.MappingNavProperties.Add(item.Key, mappingNavColumnInfo); } } } } private static void AddAppendProperties(IEnumerable> navManages, AppendNavInfo navInfo, List entityColumns, IEnumerable pkColumns) { foreach (var item in pkColumns) { navInfo.AppendProperties.Add(item.PropertyName, item.DbColumnName); } foreach (var item in navManages) { var FirstExp = item.Expressions.First(); var navName = ExpressionTool.GetMemberName(FirstExp); if (FirstExp is LambdaExpression &&ExpressionTool.GetMethodName((FirstExp as LambdaExpression).Body) == "ToList") { navName = ExpressionTool.GetFirstTypeNameFromExpression(FirstExp); } var navColumn = entityColumns.Where(it => it.IsPrimarykey == false).Where(it => it.Navigat != null).FirstOrDefault(it => it.PropertyName == navName); if (navColumn != null && navColumn.Navigat.NavigatType != NavigateType.ManyToMany) { var name1 = navColumn.Navigat.Name; var name2 = navColumn.Navigat.Name2; var name1Column = entityColumns.FirstOrDefault(it => it.PropertyName == name1); var name2Column = entityColumns.FirstOrDefault(it => it.PropertyName == name2); if (name1Column != null) { if (!navInfo.AppendProperties.ContainsKey(name1Column.PropertyName)) navInfo.AppendProperties.Add(name1Column.PropertyName, name1Column.DbColumnName); } if (name2Column != null) { if (!navInfo.AppendProperties.ContainsKey(name2Column.PropertyName)) navInfo.AppendProperties.Add(name2Column.PropertyName, name2Column.DbColumnName); } if (navColumn.Navigat.NavigatType == NavigateType.Dynamic && name1.HasValue()) { var jarray= JArray.Parse(name1); foreach (var jitem in jarray) { var columnInfo = entityColumns.FirstOrDefault(it => it.PropertyName.EqualCase(jitem["m"].ToString())|| it.DbColumnName.EqualCase(jitem["m"].ToString())); if (columnInfo != null) { if(!navInfo.AppendProperties.ContainsKey(columnInfo.PropertyName)) navInfo.AppendProperties.Add(columnInfo.PropertyName, columnInfo.DbColumnName); } } } } } } private async Task _InitNavigatAsync(List result) { if (this.QueryBuilder.Includes != null) { await Task.Run(() => { _InitNavigat(result); }); } } private void _InitNavigat(List result) { if (this.QueryBuilder.Includes != null) { var managers = (this.QueryBuilder.Includes as List); if (this.QueryBuilder.AppendNavInfo?.AppendProperties?.Any()==true) { if (result.HasValue()) { SelectNavQuery(result, managers); } } else { foreach (var it in managers) { var manager = it as NavigatManager; if (manager != null) { manager.RootList = result; manager.Execute(); } } } } } private void SelectNavQuery(List result, List managers) { if (result.Any()) { IList outList = null; foreach (var it in managers) { var manager = it; var p = it.GetType().GetProperty("RootList"); var tType = it.GetType().GenericTypeArguments[0]; var allColumns = this.Context.EntityMaintenance.GetEntityInfo(tType) .Columns; var columns = allColumns .Where(a => this.QueryBuilder.AppendNavInfo.Result.First().result.ContainsKey("SugarNav_" + a.PropertyName)) .ToList(); var listType = typeof(List<>).MakeGenericType(tType); if (outList == null) { outList = SelectNavQuery_SetList(result, it, p, tType, columns, listType); } else { p.SetValue(it, outList); } it.GetType().GetMethod("Execute").Invoke(it, null); SelectNavQuery_MappingList(it, result, outList, allColumns.Where(a => a.Navigat != null).ToList()); } } } private void SelectNavQuery_MappingList(object it,List result, IList outList,List columnInfos) { for (int i = 0; i < result.Count; i++) { var leftObject = result[i]; var rightObject = outList[i]; foreach (var item in this.QueryBuilder.AppendNavInfo.MappingNavProperties) { var rightName = item.Value.Name; var rightColumnInfo = columnInfos.FirstOrDefault(a => a.PropertyName == rightName); var anyParent = item.Value.ParentName.HasValue(); if (anyParent) { rightColumnInfo = columnInfos.FirstOrDefault(a => a.PropertyName == item.Value.ParentName); } var rightValue=rightColumnInfo.PropertyInfo.GetValue(rightObject); var leftName = item.Key; if (anyParent) { if (rightValue == null) { rightValue = UtilMethods.GetDefaultValue(rightColumnInfo.PropertyInfo.PropertyType); } rightValue = rightValue.GetType().GetProperty(item.Value.Name).GetValue(rightValue); } //// var rightColumn=col // object value = item; if (item.Value.ExpressionList.Count > 1 && rightValue != null) { //foreach (var callExp in item.Value.ExpressionList.Skip(1)) //{ try { MethodCallExpression meExp = (MethodCallExpression)item.Value.ExpressionList.Last(); ParameterExpression ps = ExpressionTool.GetParameters(meExp).First(); var comExp = Expression.Lambda(meExp, ps); var obj = comExp.Compile(); // 传递参数值 var leftValue = obj.DynamicInvoke(rightObject); UtilMethods.SetAnonymousObjectPropertyValue(leftObject, leftName, leftValue); } catch(Exception ex) { var errorExp = item.Value.ExpressionList.Last().ToString(); Check.ExceptionEasy($"{errorExp} no support,{ex.Message}", $"{errorExp}语法不支持,请查SqlSugar文档询导航DTO用法,{ex.Message}"); } // // 重新构造Lambda表达式,将参数替换为新的参数,方法调用替换为新的方法调用 // var newExpression = Expression.Lambda>>(newMethodCallExpr, paramExpr); // Expression.Call(callExp, (callExp as MethodCallExpression).Method,new ) // var propertyExpr = Expression.Property(paramExpr, rightName); // } } else if(rightValue != null) { //leftObject.GetType().GetProperty(leftName).SetValue(leftObject, rightValue); UtilMethods.SetAnonymousObjectPropertyValue(leftObject, leftName, rightValue); } } } } private IList SelectNavQuery_SetList(List result, object it, PropertyInfo p, Type tType, List columns, Type listType) { var outList = Activator.CreateInstance(listType); p.SetValue(it, outList); var index = 0; foreach (var item in result) { var addItem = Activator.CreateInstance(tType); var appendResult = this.QueryBuilder.AppendNavInfo.Result[index]; foreach (var kv in appendResult.result) { var propertyName = kv.Key.Replace("SugarNav_", ""); var propertyInfo = columns.First(i => i.PropertyName == propertyName).PropertyInfo; if (kv.Value is decimal && UtilMethods.GetUnderType(propertyInfo.PropertyType).IsIn(typeof(int), typeof(long))) { var changeValue = UtilMethods.ChangeType2(kv.Value, propertyInfo.PropertyType); propertyInfo.SetValue(addItem, changeValue); } else if (kv.Value == DBNull.Value && UtilMethods.GetUnderType(propertyInfo.PropertyType).IsIn(typeof(int), typeof(long))) { var changeValue = UtilMethods.ChangeType2(0, propertyInfo.PropertyType); propertyInfo.SetValue(addItem, changeValue); } else if (kv.Value == DBNull.Value) { propertyInfo.SetValue(addItem, null); } else if (UtilMethods.GetUnderType(propertyInfo.PropertyType) == typeof(Guid) && kv.Value is string) { propertyInfo.SetValue(addItem, new Guid(kv.Value.ToString())); } else if (UtilMethods.GetUnderType(propertyInfo.PropertyType) == typeof(int) && kv.Value is long) { propertyInfo.SetValue(addItem, Convert.ToInt32(kv.Value)); } else if (propertyInfo.PropertyType.FullName == "System.Ulid") { propertyInfo.SetValue(addItem,UtilMethods.To( kv.Value, propertyInfo.PropertyType)); } else { propertyInfo.SetValue(addItem, kv.Value); } } (outList as IList).Add(addItem); index++; } return outList as IList; } private bool IsSelectNavQuery() { return this.QueryBuilder.SelectValue.HasValue() && this.QueryBuilder.NoCheckInclude == false; } protected void _Mapper(List result) { if (this.EntityInfo.Columns.Any(it => it.IsTranscoding)) { foreach (var item in result) { foreach (var column in this.EntityInfo.Columns.Where(it => it.IsTranscoding)) { var value = column.PropertyInfo.GetValue(item, null); if (value != null) { column.PropertyInfo.SetValue(item, UtilMethods.DecodeBase64(value.ToString()), null); } } } } if (this.Mappers.HasValue()) { foreach (var mapper in this.Mappers) { if (typeof(TResult) == typeof(T)) { mapper(result.Select(it => (T)Convert.ChangeType(it, typeof(T))).ToList()); } else { Check.Exception(true, "{0} and {1} are not a type, Try .select().mapper().ToList", typeof(TResult).FullName, typeof(T).FullName); } } } if (this.MapperAction != null) { foreach (TResult item in result) { if (typeof(TResult) == typeof(T)) { foreach (var mapper in this.MapperAction) { mapper((T)(item as object)); } } else { Check.Exception(true, "{0} and {1} are not a type, Try .select().mapper().ToList", typeof(TResult).FullName, typeof(T).FullName); } } } if (this.MapperActionWithCache != null) { if (typeof(TResult) == typeof(T)) { var list = (List)Convert.ChangeType(result, typeof(List)); var mapperCache = new MapperCache(list, this.Context); foreach (T item in list) { mapperCache.GetIndex = 0; this.MapperActionWithCache(item, mapperCache); } } else { Check.Exception(true, "{0} and {1} are not a type, Try .select().mapper().ToList", typeof(TResult).FullName, typeof(T).FullName); } } } private ISugarQueryable _Mapper(Expression mapperObject, Expression mapperField) { if ((mapperObject as LambdaExpression).Body is UnaryExpression) { mapperObject = ((mapperObject as LambdaExpression).Body as UnaryExpression).Operand; } else { mapperObject = (mapperObject as LambdaExpression).Body; } if ((mapperField as LambdaExpression).Body is UnaryExpression) { mapperField = ((mapperField as LambdaExpression).Body as UnaryExpression).Operand; } else { mapperField = (mapperField as LambdaExpression).Body; } Check.Exception(mapperObject is MemberExpression == false || mapperField is MemberExpression == false, ".Mapper() parameter error"); var mapperObjectExp = mapperObject as MemberExpression; var mapperFieldExp = mapperField as MemberExpression; Check.Exception(mapperFieldExp.Type.IsClass(), ".Mapper() parameter error"); var objType = mapperObjectExp.Type; var filedType = mapperFieldExp.Expression.Type; Check.Exception(objType != typeof(TObject) && objType != typeof(List), ".Mapper() parameter error"); if (objType == typeof(List)) { objType = typeof(TObject); } var filedName = mapperFieldExp.Member.Name; var objName = mapperObjectExp.Member.Name; var filedEntity = this.Context.EntityMaintenance.GetEntityInfo(objType); var objEntity = this.Context.EntityMaintenance.GetEntityInfo(filedType); var isSelf = filedType == typeof(T); if (Mappers == null) Mappers = new List>>(); if (isSelf) { Action> mapper = (entitys) => { if (entitys.IsNullOrEmpty() || !entitys.Any()) return; var entity = entitys.First(); var whereCol = filedEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals(filedName, StringComparison.CurrentCultureIgnoreCase)); if (whereCol == null) { whereCol = filedEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); } if (whereCol == null) { whereCol = filedEntity.Columns.FirstOrDefault(it => GetPrimaryKeys().Any(pk => pk.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))); } if (whereCol == null) { whereCol = filedEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals("id", StringComparison.CurrentCultureIgnoreCase)); } if (whereCol == null) { whereCol = filedEntity.Columns.FirstOrDefault(it => (it.PropertyName).Equals(it.EntityName + "id", StringComparison.CurrentCultureIgnoreCase)); } if (whereCol == null) { Check.Exception(true, ".Mapper() parameter error"); } List inValues = entitys.Select(it => it.GetType().GetProperty(filedName).GetValue(it, null).ObjToString()).ToList(); if (inValues != null && inValues.Any() && UtilMethods.GetUnderType(entitys.First().GetType().GetProperty(filedName).PropertyType) == UtilConstants.GuidType) { inValues = inValues.Select(x => x == "" ? "null" : x).Distinct().ToList(); } List wheres = new List() { new ConditionalModel() { FieldName=this.SqlBuilder.GetTranslationColumnName(whereCol.DbColumnName), ConditionalType= ConditionalType.In, FieldValue=string.Join(",",inValues.Distinct()), CSharpTypeName=whereCol.PropertyInfo.PropertyType.Name } }; var list = this.Context.Queryable().Where(wheres).ToList(); foreach (var item in entitys) { var whereValue = item.GetType().GetProperty(filedName).GetValue(item, null); var setValue = list.Where(x => x.GetType().GetProperty(whereCol.PropertyName).GetValue(x, null).ObjToString() == whereValue.ObjToString()).ToList(); var setObject = item.GetType().GetProperty(objName); if (setObject.PropertyType.FullName.IsCollectionsList()) { setObject.SetValue(item, setValue.ToList(), null); } else { setObject.SetValue(item, setValue.FirstOrDefault(), null); } } }; Mappers.Add(mapper); } else { Action> mapper = (entitys) => { if (entitys.IsNullOrEmpty() || !entitys.Any()) return; var entity = entitys.First(); var tEntity = this.Context.EntityMaintenance.GetEntityInfo(); var whereCol = tEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals(filedName, StringComparison.CurrentCultureIgnoreCase)); if (whereCol == null) { whereCol = tEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); } if (whereCol == null) { whereCol = tEntity.Columns.FirstOrDefault(it => GetPrimaryKeys().Any(pk => pk.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))); } if (whereCol == null) { whereCol = tEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals("id", StringComparison.CurrentCultureIgnoreCase)); } if (whereCol == null) { whereCol = tEntity.Columns.FirstOrDefault(it => (it.PropertyName).Equals(it.EntityName + "id", StringComparison.CurrentCultureIgnoreCase)); } if (whereCol == null) { Check.Exception(true, ".Mapper() parameter error"); } List inValues = entitys.Select(it => it.GetType().GetProperty(whereCol.PropertyName).GetValue(it, null).ObjToString()).ToList(); var dbColumnName = filedEntity.Columns.FirstOrDefault(it => it.PropertyName == filedName).DbColumnName; List wheres = new List() { new ConditionalModel() { FieldName=dbColumnName, ConditionalType= ConditionalType.In, FieldValue=string.Join(",",inValues) } }; var list = this.Context.Queryable().Where(wheres).ToList(); foreach (var item in entitys) { var whereValue = item.GetType().GetProperty(whereCol.PropertyName).GetValue(item, null); var setValue = list.Where(x => x.GetType().GetProperty(filedName).GetValue(x, null).ObjToString() == whereValue.ObjToString()).ToList(); var setObject = item.GetType().GetProperty(objName); if (setObject.PropertyType.FullName.IsCollectionsList()) { setObject.SetValue(item, setValue.ToList(), null); } else { setObject.SetValue(item, setValue.FirstOrDefault(), null); } } }; Mappers.Add(mapper); } return this; } private ISugarQueryable _Mapper(Expression mapperObject, Expression mainField, Expression childField) { if ((mapperObject as LambdaExpression).Body is UnaryExpression) { mapperObject = ((mapperObject as LambdaExpression).Body as UnaryExpression).Operand; } else { mapperObject = (mapperObject as LambdaExpression).Body; } if ((mainField as LambdaExpression).Body is UnaryExpression) { mainField = ((mainField as LambdaExpression).Body as UnaryExpression).Operand; } else { mainField = (mainField as LambdaExpression).Body; } if ((childField as LambdaExpression).Body is UnaryExpression) { childField = ((childField as LambdaExpression).Body as UnaryExpression).Operand; } else { childField = (childField as LambdaExpression).Body; } Check.Exception(mapperObject is MemberExpression == false || mainField is MemberExpression == false, ".Mapper() parameter error"); var mapperObjectExp = mapperObject as MemberExpression; var mainFieldExp = mainField as MemberExpression; var childFieldExp = childField as MemberExpression; Check.Exception(mainFieldExp.Type.IsClass(), ".Mapper() parameter error"); Check.Exception(childFieldExp.Type.IsClass(), ".Mapper() parameter error"); var objType = mapperObjectExp.Type; var filedType = mainFieldExp.Expression.Type; Check.Exception(objType != typeof(TObject) && objType != typeof(List), ".Mapper() parameter error"); if (objType == typeof(List)) { objType = typeof(TObject); } var mainFiledName = mainFieldExp.Member.Name; var childFiledName = childFieldExp.Member.Name; var objName = mapperObjectExp.Member.Name; var filedEntity = this.Context.EntityMaintenance.GetEntityInfo(objType); var objEntity = this.Context.EntityMaintenance.GetEntityInfo(filedType); var isSelf = filedType == typeof(T); if (Mappers == null) Mappers = new List>>(); if (isSelf) { Action> mapper = (entitys) => { if (entitys.IsNullOrEmpty() || !entitys.Any()) return; var entity = entitys.First(); var whereCol = filedEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals(childFiledName, StringComparison.CurrentCultureIgnoreCase)); if (whereCol == null) { whereCol = filedEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); } if (whereCol == null) { whereCol = filedEntity.Columns.FirstOrDefault(it => GetPrimaryKeys().Any(pk => pk.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))); } if (whereCol == null) { whereCol = filedEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals("id", StringComparison.CurrentCultureIgnoreCase)); } if (whereCol == null) { whereCol = filedEntity.Columns.FirstOrDefault(it => (it.PropertyName).Equals(it.EntityName + "id", StringComparison.CurrentCultureIgnoreCase)); } if (whereCol == null) { Check.Exception(true, ".Mapper() parameter error"); } List inValues = entitys.Select(it => it.GetType().GetProperty(mainFiledName).GetValue(it, null).ObjToString()).ToList(); List wheres = new List() { new ConditionalModel() { FieldName=whereCol.DbColumnName, ConditionalType= ConditionalType.In, FieldValue=string.Join(",",inValues.Distinct()) } }; var list = this.Context.Queryable().Where(wheres).ToList(); foreach (var item in entitys) { var whereValue = item.GetType().GetProperty(mainFiledName).GetValue(item, null); var setValue = list.Where(x => x.GetType().GetProperty(whereCol.PropertyName).GetValue(x, null).ObjToString() == whereValue.ObjToString()).ToList(); var setObject = item.GetType().GetProperty(objName); if (setObject.PropertyType.FullName.IsCollectionsList()) { setObject.SetValue(item, setValue.ToList(), null); } else { setObject.SetValue(item, setValue.FirstOrDefault(), null); } } }; Mappers.Add(mapper); } else { Action> mapper = (entitys) => { if (entitys.IsNullOrEmpty() || !entitys.Any()) return; var entity = entitys.First(); var tEntity = this.Context.EntityMaintenance.GetEntityInfo(); var whereCol = tEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals(childFiledName, StringComparison.CurrentCultureIgnoreCase)); if (whereCol == null) { whereCol = tEntity.Columns.FirstOrDefault(it => it.IsPrimarykey == true); } if (whereCol == null) { whereCol = tEntity.Columns.FirstOrDefault(it => GetPrimaryKeys().Any(pk => pk.Equals(it.DbColumnName, StringComparison.CurrentCultureIgnoreCase))); } if (whereCol == null) { whereCol = tEntity.Columns.FirstOrDefault(it => it.PropertyName.Equals("id", StringComparison.CurrentCultureIgnoreCase)); } if (whereCol == null) { whereCol = tEntity.Columns.FirstOrDefault(it => (it.PropertyName).Equals(it.EntityName + "id", StringComparison.CurrentCultureIgnoreCase)); } if (whereCol == null) { Check.Exception(true, ".Mapper() parameter error"); } List inValues = entitys.Select(it => it.GetType().GetProperty(whereCol.PropertyName).GetValue(it, null).ObjToString()).ToList(); var dbColumnName = filedEntity.Columns.FirstOrDefault(it => it.PropertyName == mainFiledName).DbColumnName; List wheres = new List() { new ConditionalModel() { FieldName=dbColumnName, ConditionalType= ConditionalType.In, FieldValue=string.Join(",",inValues) } }; var list = this.Context.Queryable().Where(wheres).ToList(); foreach (var item in entitys) { var whereValue = item.GetType().GetProperty(whereCol.PropertyName).GetValue(item, null); var setValue = list.Where(x => x.GetType().GetProperty(mainFiledName).GetValue(x, null).ObjToString() == whereValue.ObjToString()).ToList(); var setObject = item.GetType().GetProperty(objName); if (setObject.PropertyType.FullName.IsCollectionsList()) { setObject.SetValue(item, setValue.ToList(), null); } else { setObject.SetValue(item, setValue.FirstOrDefault(), null); } } }; Mappers.Add(mapper); } return this; } private void SetContextModel(List result, Type entityType) { if (result.HasValue()) { if (UtilMethods.GetRootBaseType(entityType).HasValue() && UtilMethods.GetRootBaseType(entityType) == UtilConstants.ModelType) { foreach (var item in result) { var contextProperty = item.GetType().GetProperty("Context"); SqlSugarProvider newClient = this.Context.Utilities.CopyContext(); newClient.Ado.IsDisableMasterSlaveSeparation = true; if (newClient.CurrentConnectionConfig.AopEvents == null) newClient.CurrentConnectionConfig.AopEvents = new AopEvents(); contextProperty.SetValue(item, newClient, null); } } } } #endregion #region Mapping Type protected void RestoreMapping() { if (IsAs && _RestoreMapping) { this.Context.MappingTables = OldMappingTableList == null ? new MappingTableList() : OldMappingTableList; } } protected void InitMapping() { if (this.QueryableMappingTableList != null) this.Context.MappingTables = this.QueryableMappingTableList; } #endregion #region Other private bool IsSingleWithChildTableQuery() { return this.QueryBuilder.IsSingle() && this.QueryBuilder.TableShortName.HasValue(); } private Expression> ReplaceMasterTableParameters(Expression> expression) { var parameterName = (expression as LambdaExpression)?.Parameters?.FirstOrDefault()?.Name; if (parameterName != null && parameterName != this.QueryBuilder.TableShortName) { expression = ExpressionTool.ChangeLambdaExpression(expression, parameterName, this.QueryBuilder.TableShortName); } return expression; } private void orderPropertyNameByJoin(string orderPropertyName, OrderByType? orderByType) { var shortName = orderPropertyName.Split('.').FirstOrDefault(); orderPropertyName = orderPropertyName.Split('.').Last(); var entityType = this.QueryBuilder.JoinQueryInfos.FirstOrDefault(it => it.ShortName.EqualCase(shortName))?.EntityType; if (entityType == null) { entityType=this.EntityInfo.Type; } if (this.Context.EntityMaintenance.GetEntityInfoWithAttr(entityType).Columns.Any(it => it.DbColumnName?.EqualCase(orderPropertyName) == true || it.PropertyName?.EqualCase(orderPropertyName) == true)) { var name = this.Context.EntityMaintenance.GetEntityInfoWithAttr(entityType).Columns.FirstOrDefault(it => it.DbColumnName?.EqualCase(orderPropertyName) == true || it.PropertyName?.EqualCase(orderPropertyName) == true)?.DbColumnName; this.OrderBy(this.SqlBuilder.GetTranslationColumnName(shortName)+"."+this.SqlBuilder.GetTranslationColumnName(name) + " " + orderByType); } else { Check.ExceptionEasy($"OrderByPropertyName error.{orderPropertyName} does not exist in the entity class", $"OrderByPropertyName出错实体类中不存在{orderPropertyName}"); } } private void OutIntoTableSql(string TableName, out KeyValuePair> sqlInfo, out string sql,Type tableInfo) { var columnList = this.Context.EntityMaintenance.GetEntityInfo(tableInfo).Columns; //var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(TableEntityType); sqlInfo = this.ToSql(); var name = this.SqlBuilder.GetTranslationTableName(TableName); var columns = ""; sql = ""; var isSqlFunc = this.QueryBuilder.SelectValue is Expression; if (isSqlFunc) { columns = "("; foreach (var item in ExpressionTool.GetNewExpressionItemList((Expression)this.QueryBuilder.SelectValue)) { var column = item.Key; var columnInfo = columnList.FirstOrDefault(it => it.PropertyName == item.Key); if (columnInfo != null) { column =this.SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); } columns += $"{column},"; } columns = columns.TrimEnd(',') + ")"; sql = $" INSERT INTO {name} {columns} " + sqlInfo.Key; } else { //if (this.QueryBuilder.GetSelectValue != null && this.QueryBuilder.GetSelectValue.Contains(",")) ; //{ columns = "("; foreach (var item in this.QueryBuilder.GetSelectValue.Split(',')) { var column = Regex.Split(item, " AS ").Last().Trim(); var columnInfo= columnList.FirstOrDefault(it => SqlBuilder.GetTranslationColumnName(it.PropertyName) == column); if (columnInfo != null) { column = SqlBuilder.GetTranslationColumnName(columnInfo.DbColumnName); } columns += $"{column},"; } columns = columns.TrimEnd(',') + ")"; //} sql = $" INSERT INTO {name} {columns} " + sqlInfo.Key; } } internal string GetTableName(EntityInfo entity, string tableName) { var oldTableName = tableName; var attr = entity?.Type?.GetCustomAttribute(); var configId = ((object)this.Context.CurrentConnectionConfig.ConfigId).ObjToString(); if (attr != null && configId != attr.configId.ObjToString()) { var dbName = this.Context.Root.GetConnection(attr.configId).Ado.Connection.Database; var guidPoint = Guid.NewGuid().ObjToString(); dbName=dbName.Replace(".", guidPoint); tableName = this.Context.Root.GetConnection(attr.configId).EntityMaintenance.GetEntityInfo(entity.Type).DbTableName; oldTableName = tableName; tableName = this.QueryBuilder.LambdaExpressions.DbMehtods.GetTableWithDataBase (this.QueryBuilder.Builder.GetTranslationColumnName(dbName), this.QueryBuilder.Builder.GetTranslationColumnName(tableName)); tableName = tableName.Replace(guidPoint, "."); } if (attr != null && configId != attr.configId.ObjToString()) { var dbLinkName = this.Context.Root.GetConnection(attr.configId).CurrentConnectionConfig.DbLinkName; if (dbLinkName != null) { if (dbLinkName.First()== '@') { tableName = this.QueryBuilder.Builder.GetTranslationColumnName(oldTableName) +dbLinkName; } else if (dbLinkName.Last() == '_') { tableName = dbLinkName+oldTableName; } else { tableName = dbLinkName + "." + this.QueryBuilder.Builder.GetTranslationColumnName(oldTableName); } } } if (tableName == null) { tableName = entity.DbTableName; } return tableName; } protected string AppendSelect(List entityColumnInfos,string sql, ReadOnlyCollection parameters, List columnsResult, int parameterIndex1) { //var lowerSql = sql.ToLower(); //var isSubquery = lowerSql.Contains("select ") && ExpressionTool.IsMemberInit(this.QueryBuilder.SelectValue); //if (isSubquery) //{ return AppendSelectWithSubQuery(entityColumnInfos, sql, parameters, columnsResult, parameterIndex1); //} //var columns = entityColumnInfos; //var parameterName = parameters[parameterIndex1]; //foreach (var item in columns) //{ // if (item.IsIgnore == false && columnsResult.Any(it => it.PropertyName.EqualCase(item.PropertyName)) && !lowerSql.Contains(SqlBuilder.GetTranslationColumnName(item.PropertyName.ToLower()))) // { // if (item.EntityName == this.QueryBuilder.EntityName&&sql.StartsWith("*,")) // { // continue; // } // sql = $" {sql},{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)} "; // } //} //return sql; } private string AppendSelectWithSubQuery(List entityColumnInfos, string sql, ReadOnlyCollection parameters, List columnsResult, int parameterIndex1,string parameterName) { var list = ExpressionTool.GetMemberInit(this.QueryBuilder.SelectValue)?.Bindings?.Cast() ?.Select(it => it.Member.Name)?.ToList()??new List(); var columns = entityColumnInfos; //var parameterName = parameters[parameterIndex1]; if (this.QueryBuilder.AutoAppendedColumns == null) { this.QueryBuilder.AutoAppendedColumns = new List(); } foreach (var item in columns) { if (item.IsIgnore == false && !this.QueryBuilder.AutoAppendedColumns.Contains(item.PropertyName) && columnsResult.Any(it => it.PropertyName.EqualCase(item.PropertyName)) && !list.Any(it => it.EqualCase(item.PropertyName))) { if (!sql.Contains($"{SqlBuilder.GetTranslationColumnName(parameterName)}.{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)}")&& !sql.Contains($"{SqlBuilder.GetTranslationColumnName(parameterName)}.{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)}")) { sql = $" {sql},{SqlBuilder.GetTranslationColumnName(parameterName)}.{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)} "; this.QueryBuilder.AutoAppendedColumns.Add(item.PropertyName); } } } return sql; } private string AppendSelectWithSubQuery(List entityColumnInfos, string sql, ReadOnlyCollection parameters, List columnsResult, int parameterIndex1) { var list = ExpressionTool.GetMemberInit(this.QueryBuilder.SelectValue).Bindings.Cast() .Select(it => it.Member.Name).ToList(); var columns = entityColumnInfos; var parameterName = parameters[parameterIndex1]; if (this.QueryBuilder.AutoAppendedColumns == null) { this.QueryBuilder.AutoAppendedColumns = new List(); } foreach (var item in columns) { if (item.IsIgnore == false &&!this.QueryBuilder.AutoAppendedColumns.Contains(item.PropertyName)&& columnsResult.Any(it => it.PropertyName.EqualCase(item.PropertyName))&& !list.Any(it=>it.EqualCase(item.PropertyName))) { if (!sql.Contains($"{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)}")&& !sql.Contains($"{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)}")) { if (parameterIndex1==0&&this.QueryBuilder.JoinQueryInfos.Any()) { sql = $" {sql},{SqlBuilder.GetTranslationColumnName(this.QueryBuilder.TableShortName)}.{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)} "; this.QueryBuilder.AutoAppendedColumns.Add(item.PropertyName); } else { sql = $" {sql},{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)} "; this.QueryBuilder.AutoAppendedColumns.Add(item.PropertyName); } } } } return sql; } protected string AppendSelect(string sql, ReadOnlyCollection parameters, List columnsResult, int parameterIndex1) { var columns = this.Context.EntityMaintenance.GetEntityInfoWithAttr(typeof(EntityType)).Columns; //var lowerSql = sql.ToLower(); //var isSubquery = lowerSql.Contains("select ") && ExpressionTool.IsMemberInit(this.QueryBuilder.SelectValue); //if (isSubquery) //{ return AppendSelectWithSubQuery(columns, sql, parameters, columnsResult, parameterIndex1, parameters[parameterIndex1].Name); //} //var parameterName = parameters[parameterIndex1].Name; //if (parameterName.HasValue()) //{ // parameterName = this.SqlBuilder.GetTranslationColumnName(parameterName); //} //foreach (var item in columns) //{ // if (item.IsIgnore == false && columnsResult.Any(it => it.PropertyName.EqualCase(item.PropertyName)) && !sql.ToLower().Contains(SqlBuilder.GetTranslationColumnName(item.PropertyName).ToLower())) // { // if (!sql.Contains($"{parameterName}.{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)}")&& // !sql.Contains($"{parameterName}.{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)}")) // { // sql = $" {sql},{parameterName}.{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)} "; // } // } //} //return sql; } internal JoinQueryInfo GetJoinInfo(Expression joinExpression, JoinType joinType) { QueryBuilder.CheckExpressionNew(joinExpression, "Join"); QueryBuilder.JoinExpression = joinExpression; var express = LambdaExpression.Lambda(joinExpression).Body; var lastPareamter = (express as LambdaExpression).Parameters.Last(); var expResult = this.QueryBuilder.GetExpressionValue(joinExpression, ResolveExpressType.WhereMultiple); this.Context.InitMappingInfo(lastPareamter.Type); var result = new JoinQueryInfo() { JoinIndex = QueryBuilder.JoinQueryInfos.Count, JoinType = joinType, JoinWhere = expResult.GetResultString(), ShortName = lastPareamter.Name, EntityType= lastPareamter.Type, TableName = null }; if (QueryBuilder.IsCrossQueryWithAttr) { result.TableName = GetTableName(this.Context.EntityMaintenance.GetEntityInfoWithAttr(lastPareamter.Type), result.TableName); } else { result.TableName= this.Context.EntityMaintenance.GetTableName(lastPareamter.Type); } if (this.Context.CurrentConnectionConfig?.MoreSettings?.PgSqlIsAutoToLower == false) { result.ShortName = this.SqlBuilder.GetTranslationColumnName(result.ShortName); } if (this.EntityInfo.Type == result.EntityType&&this.QueryBuilder?.AsTables?.Count()==1) { var tableName = this.QueryBuilder.AsTables.First().Value; if (tableName.EndsWith(" MergeTable ")&&tableName?.Trim()==this.QueryBuilder.GetTableNameString?.Trim()) { this.QueryBuilder.MasterDbTableName = " (SELECT * FROM " + tableName + ")"; this.QueryBuilder.AsTables?.Clear(); } } if (result.JoinIndex == 0) { var firstPareamter = (express as LambdaExpression).Parameters.First(); this.QueryBuilder.TableShortName = firstPareamter.Name; if (this.QueryBuilder.AsTables != null && this.QueryBuilder.AsTables.Count == 1) { var tableinfo = this.QueryBuilder.AsTables.First(); if (this.QueryBuilder.TableWithString != SqlWith.Null && this.Context.CurrentConnectionConfig?.MoreSettings?.IsWithNoLockQuery == true && this.QueryBuilder.AsTables.First().Value.ObjToString().Contains(SqlWith.NoLock) == false) { if (this.QueryBuilder.AsTables.First().Value.EndsWith(") unionTable ")) { this.QueryBuilder.AsTables[tableinfo.Key] = " (SELECT * FROM " + this.QueryBuilder.AsTables.First().Value + ")"; } else if (this.QueryBuilder.AsTables.First().Value.EndsWith(") MergeTable ")) { this.QueryBuilder.AsTables[tableinfo.Key] = " (SELECT * FROM " + this.QueryBuilder.AsTables.First().Value + ")"; } else { this.QueryBuilder.AsTables[tableinfo.Key] = " (SELECT * FROM " + this.QueryBuilder.AsTables.First().Value + $" {SqlWith.NoLock} )"; } } else if (this.QueryBuilder.IsSqlQuery && this.QueryBuilder.AsTables.First().Value.ObjToString().StartsWith("(")) { var tableName = this.QueryBuilder.AsTables.First().Value; this.QueryBuilder.AsTables[tableinfo.Key] = " (SELECT * FROM " + tableName + ")" + this.QueryBuilder.TableShortName; } else { var tableName = this.QueryBuilder.AsTables.First().Value; if (tableName != null && Regex.IsMatch(tableName.Replace(".", "").Replace("-",""), @"^\w+$")) { tableName = SqlBuilder.GetTranslationTableName(tableName); } this.QueryBuilder.AsTables[tableinfo.Key] = " (SELECT * FROM " + tableName + ")"; } this.QueryBuilder.SelectValue =this.SqlBuilder.GetTranslationColumnName(this.QueryBuilder.TableShortName) + ".*"; } } Check.Exception(result.JoinIndex > 10, ErrorMessage.GetThrowMessage("只支持12个表", "Only 12 tables are supported")); return result; } protected ISugarQueryable _Select(Expression expression) { QueryBuilder.CheckExpression(expression, "Select"); this.Context.InitMappingInfo(typeof(TResult)); var result = InstanceFactory.GetQueryable(this.Context.CurrentConnectionConfig); result.Context = this.Context; result.SqlBuilder = this.SqlBuilder; result.SqlBuilder.QueryBuilder.Parameters = QueryBuilder.Parameters; result.SqlBuilder.QueryBuilder.SelectValue = expression; result.SqlBuilder.QueryBuilder.IsSelectSingleFiledJson = UtilMethods.IsJsonMember(expression, this.Context); result.SqlBuilder.QueryBuilder.IsSelectSingleFiledArray = UtilMethods.IsArrayMember(expression, this.Context); if (this.IsCache) { result.WithCache(this.CacheTime); } if (this.QueryBuilder.IsSqlQuery) { this.QueryBuilder.IsSqlQuerySelect = true; } return result; } protected void _Where(Expression expression) { QueryBuilder.CheckExpression(expression, "Where"); var isSingle = QueryBuilder.IsSingle(); var result = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple); QueryBuilder.WhereInfos.Add(SqlBuilder.AppendWhereOrAnd(QueryBuilder.WhereInfos.IsNullOrEmpty(), result.GetResultString())); } protected ISugarQueryable _OrderBy(Expression expression, OrderByType type = OrderByType.Asc) { QueryBuilder.CheckExpression(expression, "OrderBy"); var isSingle = QueryBuilder.IsSingle(); var member= ExpressionTool.RemoveConvert(ExpressionTool.GetLambdaExpressionBody(expression)) is MemberExpression; if (member==false&&expression.ToString().IsContainsIn("Desc(", "Asc(")) { var orderValue = ""; var newExp = (expression as LambdaExpression).Body as NewExpression; if (newExp == null) { orderValue = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple).GetResultString(); return OrderBy(orderValue); } foreach (var item in newExp.Arguments) { if (item is MemberExpression) { orderValue += QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple).GetResultString() + ","; } else { orderValue += QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple).GetResultString() + ","; } } orderValue = orderValue.TrimEnd(','); OrderBy(orderValue); return this; } else if ((expression as LambdaExpression).Body is NewExpression) { var newExp = (expression as LambdaExpression).Body as NewExpression; var result = ""; foreach (var item in newExp.Arguments) { if (item is MemberExpression&&type==OrderByType.Asc) { result += QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple).GetResultString() + ","; } else if (item is MemberExpression && type == OrderByType.Desc) { result += QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple).GetResultString() + " Desc,"; } else if (type == OrderByType.Desc) { result += QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple).GetResultString() + " Desc ,"; } else { result += QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple).GetResultString() + ","; } } result = result.TrimEnd(','); OrderBy(result); return this; } else { var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); OrderBy(lamResult.GetResultString() + UtilConstants.Space + type.ToString().ToUpper()); return this; } } private void _ToOffsetPage(int pageIndex, int pageSize) { QueryBuilder.Offset = $" OFFSET {(pageIndex - 1) * pageSize} ROWS FETCH NEXT {pageSize} ROWS ONLY"; } private int _PageList(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 pageIndex; } protected ISugarQueryable _GroupBy(Expression expression) { var oldParameterNames = this.QueryBuilder.Parameters?.Select(it => it.ParameterName) ?.ToList(); QueryBuilder.CheckExpression(expression, "GroupBy"); LambdaExpression lambda = expression as LambdaExpression; expression = lambda.Body; var isSingle = QueryBuilder.IsSingle(); ExpressionResult lamResult = null; string result = null; if (expression is NewExpression) { var newExp = expression as NewExpression; foreach (var item in newExp.Arguments) { if (item is MemberExpression) { result += QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple).GetResultString() + ","; } else { result += QueryBuilder.GetExpressionValue(item, isSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple).GetResultString() + ","; } } result = result.TrimEnd(','); } else { expression=ExpressionTool.RemoveConvert(expression); lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); result = lamResult.GetResultString(); } if (oldParameterNames != null && this.Context.CurrentConnectionConfig.DbType == DbType.SqlServer) { var newParas = this.QueryBuilder.Parameters.Where(it => !oldParameterNames.Contains(it.ParameterName)).ToList(); this.QueryBuilder.GroupParameters = newParas; var groupBySql = UtilMethods.GetSqlString(DbType.SqlServer, result, newParas.ToArray()); this.QueryBuilder.GroupBySql = groupBySql; this.QueryBuilder.GroupBySqlOld = result; GroupBy(result); } else { GroupBy(result); } return this; } protected ISugarQueryable _As(string tableName, string entityName) { if (this.QueryBuilder.AsTables != null && this.QueryBuilder.AsTables.Any(it => it.Key == entityName)) { if (this.QueryBuilder.JoinQueryInfos.Count(it => it.TableName.EqualCase(tableName)) > 1) { Check.ExceptionEasy($"if same entity name ,.LeftJoin(db.Queryable<{entityName}>,(x,y..)=>....).As(\"{tableName}\")",$"存在相同实体,请使用.LeftJoin(db.Queryable<{entityName}>).As(\"{tableName}\",(x,y..)=>...)"); } Check.Exception(true, ErrorMessage.GetThrowMessage($"use As<{tableName}>(\"{tableName}\")", $"请把 As(\"{tableName}\"), 改成 As<{tableName}实体>(\"{tableName}\")")); } else { this.QueryBuilder.AsTables.Add(entityName, tableName); } return this; } protected void _Filter(string FilterName, bool isDisabledGobalFilter) { QueryBuilder.IsDisabledGobalFilter = isDisabledGobalFilter; if (this.Context.QueryFilter.GetFilterList.HasValue() && FilterName.HasValue()) { var list = this.Context.QueryFilter.GetFilterList.Where(it => it.FilterName == FilterName && it.IsJoinQuery == !QueryBuilder.IsSingle()); foreach (var item in list) { var filterResult = item.FilterValue(this.Context); Where(filterResult.Sql + UtilConstants.Space, filterResult.Parameters); } } } public ISugarQueryable _PartitionBy(Expression expression) { QueryBuilder.CheckExpression(expression, "PartitionBy"); LambdaExpression lambda = expression as LambdaExpression; expression = lambda.Body; var isSingle = QueryBuilder.IsSingle(); ExpressionResult lamResult = null; string result = null; if (expression is NewExpression) { lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.ArraySingle : ResolveExpressType.ArrayMultiple); result = string.Join(",", lamResult.GetResultArray()); } else { lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); result = lamResult.GetResultString(); } PartitionBy(result); return this; } protected ISugarQueryable _Having(Expression expression) { QueryBuilder.CheckExpression(expression, "Having"); var isSingle = QueryBuilder.IsSingle(); var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.WhereSingle : ResolveExpressType.WhereMultiple); Having(lamResult.GetResultString()); return this; } protected List _ToList() { List result = null; var sqlObj = this._ToSql(); if (IsCache) { var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; result = CacheSchemeMain.GetOrCreate>(cacheService, this.QueryBuilder, () => { return GetData(sqlObj); }, CacheTime, this.Context, CacheKey); } else { result = GetData(sqlObj); } RestoreMapping(); _InitNavigat(result); _SubQuery(result); _Mapper(result); return result; } protected async Task> _ToListAsync() { List result = null; var sqlObj = this._ToSql(); if (IsCache) { var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService; result = CacheSchemeMain.GetOrCreate>(cacheService, this.QueryBuilder, () => { return GetData(sqlObj); }, CacheTime, this.Context, CacheKey); } else { result = await GetDataAsync(sqlObj); } RestoreMapping(); await _InitNavigatAsync(result); await _SubQueryAsync(result); _Mapper(result); return result; } private void ToSqlBefore() { var moreSetts = this.Context.CurrentConnectionConfig.MoreSettings; if (moreSetts != null && moreSetts.IsWithNoLockQuery && string.IsNullOrEmpty(QueryBuilder.TableWithString)) { if (moreSetts.DisableWithNoLockWithTran&&this.Context.Ado.IsAnyTran()) { //No With(nolock) } else { this.With(SqlWith.NoLock); } } } protected List GetData(KeyValuePair> sqlObj) { List result; var isComplexModel = QueryBuilder.IsComplexModel(sqlObj.Key); var entityType = typeof(TResult); bool isChangeQueryableSlave = GetIsSlaveQuery(); bool isChangeQueryableMasterSlave = GetIsMasterQuery(); string sqlString = sqlObj.Key; SugarParameter[] parameters = sqlObj.Value.ToArray(); var dataReader = this.Db.GetDataReader(sqlString, parameters); this.Db.GetDataBefore(sqlString, parameters); if (entityType.IsInterface) { result = GetData(isComplexModel, this.QueryBuilder.AsType, dataReader); } else { result = GetData(isComplexModel, entityType, dataReader); } this.Db.GetDataAfter(sqlString, parameters); RestChangeMasterQuery(isChangeQueryableMasterSlave); RestChangeSlaveQuery(isChangeQueryableSlave); return result; } protected async Task> GetDataAsync(KeyValuePair> sqlObj) { List result; var isComplexModel = QueryBuilder.IsComplexModel(sqlObj.Key); var entityType = typeof(TResult); bool isChangeQueryableSlave = GetIsSlaveQuery(); bool isChangeQueryableMasterSlave = GetIsMasterQuery(); string sqlString = sqlObj.Key; SugarParameter[] parameters = sqlObj.Value.ToArray(); var dataReader = await this.Db.GetDataReaderAsync(sqlString, parameters); this.Db.GetDataBefore(sqlString, parameters); if (entityType.IsInterface) { result =await GetDataAsync(isComplexModel, this.QueryBuilder.AsType, dataReader); } else { result = await GetDataAsync(isComplexModel, entityType, dataReader); } this.Db.GetDataAfter(sqlString, parameters); RestChangeMasterQuery(isChangeQueryableMasterSlave); RestChangeSlaveQuery(isChangeQueryableSlave); return result; } private List GetData(bool isComplexModel, Type entityType, IDataReader dataReader) { List result; this.Bind.QueryBuilder = this.QueryBuilder; this.Context.Utilities.QueryBuilder = this.QueryBuilder; if (entityType == UtilConstants.DynamicType) { result = this.Context.Utilities.DataReaderToExpandoObjectList(dataReader) as List; } else if (entityType.Name?.StartsWith("ValueTuple`")==true) { result = Db.Context.Utilities.DataReaderToValueTupleType(dataReader); } else if (entityType == UtilConstants.ObjType) { result = this.Context.Utilities.DataReaderToExpandoObjectList(dataReader).Select(it => ((TResult)(object)it)).ToList(); } else if (QueryBuilder.IsSelectSingleFiledJson) { result = this.Context.Utilities.DataReaderToSelectJsonList(dataReader); } else if (QueryBuilder.IsSelectSingleFiledArray) { result = this.Context.Utilities.DataReaderToSelectArrayList(dataReader); } else if (QueryBuilder.IsParameterizedConstructor || entityType.IsAnonymousType() || isComplexModel|| StaticConfig.EnableAot) { if (entityType.IsClass() == false && StaticConfig.EnableAot) { result = this.Bind.DataReaderToList(entityType, dataReader); } else { result = this.Context.Utilities.DataReaderToList(dataReader); if (StaticConfig.EnableAot) ResetNavigationPropertiesForAot(result); } } else { result = this.Bind.DataReaderToList(entityType, dataReader); } SetContextModel(result, entityType); return result; } private async Task> GetDataAsync(bool isComplexModel, Type entityType, IDataReader dataReader) { List result; this.Bind.QueryBuilder = this.QueryBuilder; this.Context.Utilities.QueryBuilder = this.QueryBuilder; if (entityType == UtilConstants.DynamicType) { result = await this.Context.Utilities.DataReaderToExpandoObjectListAsync(dataReader) as List; } else if (entityType.Name?.StartsWith("ValueTuple`") == true) { result =await Db.Context.Utilities.DataReaderToValueTupleTypeAsync(dataReader); } else if (entityType == UtilConstants.ObjType) { var expObj = await this.Context.Utilities.DataReaderToExpandoObjectListAsync(dataReader); result = expObj.Select(it => ((TResult)(object)it)).ToList(); } else if (QueryBuilder.IsSelectSingleFiledJson) { result = await this.Context.Utilities.DataReaderToSelectJsonListAsync(dataReader); } else if (QueryBuilder.IsSelectSingleFiledArray) { result =await this.Context.Utilities.DataReaderToSelectArrayListAsync(dataReader); } else if (entityType.IsAnonymousType() || isComplexModel||StaticConfig.EnableAot) { if (entityType.IsClass() == false && StaticConfig.EnableAot) { result =await this.Bind.DataReaderToListAsync(entityType, dataReader); } else { result = await this.Context.Utilities.DataReaderToListAsync(dataReader); if (StaticConfig.EnableAot) ResetNavigationPropertiesForAot(result); } } else { result = await this.Bind.DataReaderToListAsync(entityType, dataReader); } SetContextModel(result, entityType); return result; } private void ResetNavigationPropertiesForAot(List result) { if (StaticConfig.EnableAot) { var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(); var navColumnList = entityInfo.Columns.Where(it => it.Navigat != null); if (navColumnList.Any()) { foreach (var item in result) { foreach (var columnInfo in navColumnList) { columnInfo.PropertyInfo.SetValue(item, null); } } } } } protected void _InQueryable(Expression expression, KeyValuePair> sqlObj) { QueryBuilder.CheckExpression(expression, "In"); string sql = sqlObj.Key; if (sqlObj.Value.HasValue()) { this.SqlBuilder.RepairReplicationParameters(ref sql, sqlObj.Value.ToArray(), 100); this.QueryBuilder.Parameters.AddRange(sqlObj.Value); } var isSingle = QueryBuilder.IsSingle(); var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple); var fieldName = lamResult.GetResultString(); var whereSql = string.Format(this.QueryBuilder.InTemplate, fieldName, sql); this.QueryBuilder.WhereInfos.Add(SqlBuilder.AppendWhereOrAnd(this.QueryBuilder.WhereInfos.IsNullOrEmpty(), whereSql)); base._InQueryableIndex += 100; } protected List GetPrimaryKeys() { if (this.Context.IsSystemTablesConfig) { return this.Context.DbMaintenance.GetPrimaries(this.Context.EntityMaintenance.GetTableName(this.EntityInfo.EntityName)); } else { return this.EntityInfo.Columns.Where(it => it.IsPrimarykey).Select(it => it.DbColumnName).ToList(); } } protected virtual List GetIdentityKeys() { if (this.Context.IsSystemTablesConfig) { return this.Context.DbMaintenance.GetIsIdentities(this.EntityInfo.DbTableName); } else { return this.EntityInfo.Columns.Where(it => it.IsIdentity).Select(it => it.DbColumnName).ToList(); } } protected void CopyQueryBuilder(QueryBuilder asyncQueryableBuilder) { var pars = new List(); if (this.QueryBuilder.Parameters != null) { pars = this.QueryBuilder.Parameters.Select(it => new SugarParameter(it.ParameterName, it.Value) { DbType = it.DbType, Value = it.Value, ParameterName = it.ParameterName, Direction = it.Direction, IsArray = it.IsArray, IsJson = it.IsJson, IsNullable = it.IsNullable, IsRefCursor = it.IsRefCursor, Size = it.Size, SourceColumn = it.SourceColumn, SourceColumnNullMapping = it.SourceColumnNullMapping, SourceVersion = it.SourceVersion, TempDate = it.TempDate, TypeName = it.TypeName, UdtTypeName = it.UdtTypeName, IsNvarchar2=it.IsNvarchar2, _Size = it._Size }).ToList(); } asyncQueryableBuilder.IsEnableMasterSlaveSeparation = this.QueryBuilder.IsEnableMasterSlaveSeparation; asyncQueryableBuilder.TranLock = this.QueryBuilder.TranLock; asyncQueryableBuilder.IsDisableMasterSlaveSeparation = this.QueryBuilder.IsDisableMasterSlaveSeparation; asyncQueryableBuilder.IsQueryInQuery = this.QueryBuilder.IsQueryInQuery; asyncQueryableBuilder.Includes = this.QueryBuilder.Includes; asyncQueryableBuilder.Take = this.QueryBuilder.Take; asyncQueryableBuilder.Skip = this.QueryBuilder.Skip; asyncQueryableBuilder.SelectValue = this.QueryBuilder.SelectValue; asyncQueryableBuilder.WhereInfos = this.Context.Utilities.TranslateCopy(this.QueryBuilder.WhereInfos); asyncQueryableBuilder.EasyJoinInfos = this.Context.Utilities.TranslateCopy(this.QueryBuilder.EasyJoinInfos); asyncQueryableBuilder.JoinQueryInfos = QueryBuilder.JoinQueryInfos.Select(it => CopyJoinInfo(it)).ToList(); asyncQueryableBuilder.WhereIndex = this.QueryBuilder.WhereIndex; asyncQueryableBuilder.EntityType = this.QueryBuilder.EntityType; asyncQueryableBuilder.EntityName = this.QueryBuilder.EntityName; asyncQueryableBuilder.Parameters = pars; asyncQueryableBuilder.TableShortName = this.QueryBuilder.TableShortName; asyncQueryableBuilder.TableWithString = this.QueryBuilder.TableWithString; asyncQueryableBuilder.GroupByValue = this.QueryBuilder.GroupByValue; asyncQueryableBuilder.IsDistinct = this.QueryBuilder.IsDistinct; asyncQueryableBuilder.OrderByValue = this.QueryBuilder.OrderByValue; asyncQueryableBuilder.IsDisabledGobalFilter = this.QueryBuilder.IsDisabledGobalFilter; asyncQueryableBuilder.PartitionByValue = this.QueryBuilder.PartitionByValue; asyncQueryableBuilder.JoinExpression = this.QueryBuilder.JoinExpression; asyncQueryableBuilder.WhereIndex = this.QueryBuilder.WhereIndex; asyncQueryableBuilder.HavingInfos = this.QueryBuilder.HavingInfos; asyncQueryableBuilder.AsType = this.QueryBuilder.AsType; asyncQueryableBuilder.LambdaExpressions.ParameterIndex = this.QueryBuilder.LambdaExpressions.ParameterIndex; asyncQueryableBuilder.IgnoreColumns = this.Context.Utilities.TranslateCopy(this.QueryBuilder.IgnoreColumns); asyncQueryableBuilder.AsTables = this.Context.Utilities.TranslateCopy(this.QueryBuilder.AsTables); asyncQueryableBuilder.DisableTop = this.QueryBuilder.DisableTop; asyncQueryableBuilder.Offset = this.QueryBuilder.Offset; asyncQueryableBuilder.IsSqlQuery = this.QueryBuilder.IsSqlQuery; asyncQueryableBuilder.IsSqlQuerySelect = this.QueryBuilder.IsSqlQuerySelect; asyncQueryableBuilder.OldSql = this.QueryBuilder.OldSql; asyncQueryableBuilder.IsCrossQueryWithAttr = this.QueryBuilder.IsCrossQueryWithAttr; asyncQueryableBuilder.CrossQueryItems = this.QueryBuilder.CrossQueryItems; asyncQueryableBuilder.SubToListParameters = this.Context.Utilities.TranslateCopy(this.QueryBuilder.SubToListParameters); asyncQueryableBuilder.AppendColumns = this.Context.Utilities.TranslateCopy(this.QueryBuilder.AppendColumns); asyncQueryableBuilder.AppendValues = this.Context.Utilities.TranslateCopy(this.QueryBuilder.AppendValues); asyncQueryableBuilder.RemoveFilters = this.QueryBuilder.RemoveFilters?.ToArray(); asyncQueryableBuilder.Hints = this.QueryBuilder.Hints; asyncQueryableBuilder.MasterDbTableName = this.QueryBuilder.MasterDbTableName; asyncQueryableBuilder.IsParameterizedConstructor = this.QueryBuilder.IsParameterizedConstructor; asyncQueryableBuilder.GroupParameters = this.QueryBuilder.GroupParameters; asyncQueryableBuilder.GroupBySql = this.QueryBuilder.GroupBySql; asyncQueryableBuilder.GroupBySqlOld = this.QueryBuilder.GroupBySqlOld; if (this.QueryBuilder.AppendNavInfo != null) { asyncQueryableBuilder.AppendNavInfo = new AppendNavInfo() { AppendProperties= this.QueryBuilder.AppendNavInfo.AppendProperties.ToDictionary(it => it.Key, it => it.Value), MappingNavProperties= this.QueryBuilder.AppendNavInfo.MappingNavProperties.ToDictionary(it=>it.Key,it=>it.Value) } ; } } private static JoinQueryInfo CopyJoinInfo(JoinQueryInfo it) { return new JoinQueryInfo() { EntityType = it.EntityType, JoinIndex = it.JoinIndex, JoinType = it.JoinType, JoinWhere = it.JoinWhere, ShortName = it.ShortName, TableName = it.TableName }; } protected int SetCacheTime(int cacheDurationInSeconds) { if (cacheDurationInSeconds == int.MaxValue && this.Context.CurrentConnectionConfig.MoreSettings != null && this.Context.CurrentConnectionConfig.MoreSettings.DefaultCacheDurationInSeconds > 0) { cacheDurationInSeconds = this.Context.CurrentConnectionConfig.MoreSettings.DefaultCacheDurationInSeconds; } return cacheDurationInSeconds; } public virtual KeyValuePair> _ToSql() { InitMapping(); ToSqlBefore(); string sql = QueryBuilder.ToSqlString(); RestoreMapping(); return new KeyValuePair>(sql, QueryBuilder.Parameters); } #endregion #region Subquery private bool IsSubToList() { return this.QueryBuilder.SubToListParameters != null && this.QueryBuilder.SubToListParameters.Count > 0; } public virtual ISugarQueryable MergeTableWithSubToListJoin() { //_ToSql(); var clone = this.Clone(); clone.QueryBuilder.AppendValues = null; clone.QueryBuilder.SubToListParameters = null; clone.QueryBuilder.AppendColumns = null; Check.Exception(this.MapperAction != null || this.MapperActionWithCache != null, ErrorMessage.GetThrowMessage("'Mapper’ needs to be written after ‘MergeTable’ ", "Mapper 只能在 MergeTable 之后使用")); //Check.Exception(this.QueryBuilder.SelectValue.IsNullOrEmpty(),ErrorMessage.GetThrowMessage( "MergeTable need to use Queryable.Select Method .", "使用MergeTable之前必须要有Queryable.Select方法")); //Check.Exception(this.QueryBuilder.Skip > 0 || this.QueryBuilder.Take > 0 || this.QueryBuilder.OrderByValue.HasValue(),ErrorMessage.GetThrowMessage( "MergeTable Queryable cannot Take Skip OrderBy PageToList ", "使用 MergeTable不能有 Take Skip OrderBy PageToList 等操作,你可以在Mergetable之后操作")); var sqlobj = clone.ToSql(); var index = QueryBuilder.WhereIndex + 1; var result = this.Context.Queryable().AS(SqlBuilder.GetPackTable(sqlobj.Key, "MergeTable")).AddParameters(sqlobj.Value).Select("*").With(SqlWith.Null); result.QueryBuilder.WhereIndex = index; result.QueryBuilder.LambdaExpressions.ParameterIndex = QueryBuilder.LambdaExpressions.ParameterIndex++; result.QueryBuilder.LambdaExpressions.Index = QueryBuilder.LambdaExpressions.Index++; if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) { result.Select("MergeTable.*"); } result.QueryBuilder.AppendValues = this.QueryBuilder.AppendValues; result.QueryBuilder.SubToListParameters = this.QueryBuilder.SubToListParameters; result.QueryBuilder.AppendColumns = this.QueryBuilder.AppendColumns; return result; } public virtual ISugarQueryable MergeTableWithSubToList() { _ToSql(); var clone = this.Clone(); clone.QueryBuilder.AppendValues = null; clone.QueryBuilder.SubToListParameters = null; clone.QueryBuilder.AppendColumns = null; Check.Exception(this.MapperAction != null || this.MapperActionWithCache != null, ErrorMessage.GetThrowMessage("'Mapper’ needs to be written after ‘MergeTable’ ", "Mapper 只能在 MergeTable 之后使用")); //Check.Exception(this.QueryBuilder.SelectValue.IsNullOrEmpty(),ErrorMessage.GetThrowMessage( "MergeTable need to use Queryable.Select Method .", "使用MergeTable之前必须要有Queryable.Select方法")); //Check.Exception(this.QueryBuilder.Skip > 0 || this.QueryBuilder.Take > 0 || this.QueryBuilder.OrderByValue.HasValue(),ErrorMessage.GetThrowMessage( "MergeTable Queryable cannot Take Skip OrderBy PageToList ", "使用 MergeTable不能有 Take Skip OrderBy PageToList 等操作,你可以在Mergetable之后操作")); var sqlobj = clone.ToSql(); var index = QueryBuilder.WhereIndex + 1; var result = this.Context.Queryable().AS(SqlBuilder.GetPackTable(sqlobj.Key, "MergeTable")).AddParameters(sqlobj.Value).Select("*").With(SqlWith.Null); result.QueryBuilder.WhereIndex = index; result.QueryBuilder.LambdaExpressions.ParameterIndex = QueryBuilder.LambdaExpressions.ParameterIndex++; result.QueryBuilder.LambdaExpressions.Index = QueryBuilder.LambdaExpressions.Index++; if (this.Context.CurrentConnectionConfig.DbType == DbType.Oracle) { result.Select("MergeTable.*"); } result.QueryBuilder.AppendValues = this.QueryBuilder.AppendValues; result.QueryBuilder.SubToListParameters = this.QueryBuilder.SubToListParameters; result.QueryBuilder.AppendColumns = this.QueryBuilder.AppendColumns; return result; } private void _SubQuery(List result) { if (result == null || result.Count == 0) { return; } var isSubToList = this.QueryBuilder.SubToListParameters != null && this.QueryBuilder.SubToListParameters.Any(); if (!isSubToList) { return; } var appendValues = this.QueryBuilder.AppendValues; var subParamters = this.QueryBuilder.SubToListParameters; foreach (var subPara in subParamters) { if (appendValues != null) AppendSubWhereToList(result, appendValues, subPara); else AppendSubToList(result, appendValues, subPara); } } private void AppendSubToList(List result, List> appendValues, KeyValuePair subPara) { var ps = this.QueryBuilder.Parameters; var itemProperty = typeof(TResult).GetProperty(subPara.Key); var callType = itemProperty.PropertyType.GetGenericArguments().FirstOrDefault(); var isFirst = false; if (callType == null) { callType = itemProperty.PropertyType; isFirst = true; } var sql = subPara.Value.ObjToString().Replace("@sugarIndex", "0"); sql =SqlBuilder.RemoveParentheses(sql); var methodParamters = new object[] { sql, ps }; var subList = ExpressionBuilderHelper.CallFunc(callType, methodParamters, this.Clone(), "SubQueryList"); for (var i = 0; i < result.Count; i++) { var item = result[i]; var setValue = Activator.CreateInstance(itemProperty.PropertyType, true) as IList; if (typeof(TResult).IsAnonymousType()) { if (isFirst) { var jobj = JObject.FromObject(item); var prop = jobj.Property(itemProperty.Name); prop.Value = JObject.FromObject((subList as IList).Cast().FirstOrDefault()); result[i] = jobj.ToObject(); } else { var jobj = JObject.FromObject(item); var prop = jobj.Property(itemProperty.Name); prop.Value = JArray.FromObject(subList); result[i] = jobj.ToObject(); } } else { if (isFirst) { if ((subList as IList).Count > 0) { itemProperty.SetValue(item, (subList as IList)[0]); } } else { itemProperty.SetValue(item, subList); } } } } private void AppendSubWhereToList(List result, List> appendValues, KeyValuePair subPara) { var ps = this.QueryBuilder.Parameters; var index = 0; List sqls = new List(); foreach (var item in result) { var sql = subPara.Value.ObjToString(); var replaceValues = appendValues[index]; foreach (var re in replaceValues) { var config = this.Context.CurrentConnectionConfig; var p = new SugarParameter[] { new SugarParameter("@p",re.Value) }; var value = UtilMethods.GetSqlString(config.DbType, "@p", p, true); sql = sql.Replace(re.Name, value); } sql = SqlBuilder.RemoveParentheses(sql); sql = sql.Replace("@sugarIndex", index + ""); sqls.Add(sql); index++; } var itemProperty = typeof(TResult).GetProperty(subPara.Key); var callType = itemProperty.PropertyType.GetGenericArguments().FirstOrDefault(); var isFirst = false; if (callType == null) { callType = itemProperty.PropertyType; isFirst = true; } var sqlstring = string.Join(" \r\n UNION ALL ", sqls); if (callType?.IsClass() == false) { Regex regex = new Regex(@"\,\d{1,10} as sugarIndex"); sqlstring = regex.Replace(sqlstring, it=> (" as id " + it.Value)); callType = typeof(SubQueryToListDefaultT); } var methodParamters = new object[] { sqlstring, ps.ToArray() }; this.QueryBuilder.SubToListParameters = null; this.QueryBuilder.AppendColumns = new List() { new QueryableAppendColumn(){ Name="sugarIndex",AsName="sugarIndex" } }; this.QueryBuilder.AppendValues = null; var subList = ExpressionBuilderHelper.CallFunc(callType, methodParamters, this.Clone(), "SubQueryList"); var appendValue = this.QueryBuilder.AppendValues; var list = (subList as IEnumerable).Cast().ToList(); if (isFirst && !typeof(TResult).IsAnonymousType()) { SetSubListWithClassFirst(result, itemProperty, appendValue, list, 0); } else if (isFirst && typeof(TResult).IsAnonymousType()) { SetSubListWithAnonymousTypeFirst(result, itemProperty, appendValue, list, 0); } else if (typeof(TResult).IsAnonymousType()) { SetSubListWithAnonymousType(result, itemProperty, appendValue, list, 0); } else { SetSubListWithClass(result, itemProperty, appendValue, list, 0); } } private static int SetSubListWithAnonymousType(List result, PropertyInfo itemProperty, List> appendValue, List list, int resIndex) { for (int i = 0; i < result.Count; i++) { var item = result[i]; var setValue = Activator.CreateInstance(itemProperty.PropertyType, true) as IList; if (appendValue != null) { var appindex = 0; foreach (var appValue in appendValue) { if (appValue[0].Value.ObjToInt() == i) { var addItem = list[appindex]; if (addItem is SubQueryToListDefaultT) { addItem = (addItem as SubQueryToListDefaultT).id; } setValue.Add(addItem); } appindex++; } } var jobj = JObject.FromObject(item); var prop = jobj.Property(itemProperty.Name); prop.Value = JArray.FromObject(setValue); result[i] = jobj.ToObject(); //itemProperty.SetValue(item, setValue); } return resIndex; } private static int SetSubListWithAnonymousTypeFirst(List result, PropertyInfo itemProperty, List> appendValue, List list, int resIndex) { for (int i = 0; i < result.Count; i++) { var item = result[i]; object setValue = null; if (appendValue != null) { var appindex = 0; foreach (var appValue in appendValue) { if (appValue[0].Value.ObjToInt() == i) { setValue = list[appindex]; //setValue.Add(addItem); } appindex++; } } var jobj = JObject.FromObject(item); var prop = jobj.Property(itemProperty.Name); if (setValue != null) { prop.Value = JObject.FromObject(setValue); } result[i] = jobj.ToObject(); //itemProperty.SetValue(item, setValue); } return resIndex; } private static int SetSubListWithClassFirst(List result, PropertyInfo itemProperty, List> appendValue, List list, int resIndex) { foreach (var item in result) { //var setValue = Activator.CreateInstance(itemProperty.PropertyType, true); if (appendValue != null) { var appindex = 0; foreach (var appValue in appendValue) { if (appValue[0].Value.ObjToInt() == resIndex) { var addItem = list[appindex]; itemProperty.SetValue(item, addItem); } appindex++; } } //itemProperty.SetValue(item, setValue); resIndex++; } return resIndex; } private static int SetSubListWithClass(List result, PropertyInfo itemProperty, List> appendValue, List list, int resIndex) { foreach (var item in result) { var setValue = Activator.CreateInstance(itemProperty.PropertyType, true) as IList; if (appendValue != null) { var appindex = 0; foreach (var appValue in appendValue) { if (appValue[0].Value.ObjToInt() == resIndex) { var addItem = list[appindex]; if (addItem is SubQueryToListDefaultT) { addItem= ((SubQueryToListDefaultT)addItem).id; } if (addItem!=null&&addItem is string && itemProperty?.PropertyType?.GenericTypeArguments?.FirstOrDefault() == UtilConstants.GuidType) { addItem = Guid.Parse(addItem+""); } setValue.Add(addItem); } appindex++; } } itemProperty.SetValue(item, setValue); resIndex++; } return resIndex; } private async Task _SubQueryAsync(List result) { var isSubToList = this.QueryBuilder.SubToListParameters != null && this.QueryBuilder.SubToListParameters.Any(); if (!isSubToList) { return; } await Task.Run(() =>{_SubQuery(result);}); } public List SubQueryList(string sql,object parameters) { return this.Context.Ado.SqlQuery(sql,parameters); } #endregion #region Bool private bool MasterHasWhereFirstJoin() { if (this.QueryBuilder.IsSingle() == false && this.QueryBuilder.SelectValue is LambdaExpression exp &&this.QueryBuilder.AsTables?.Any()==false) { if (exp.Parameters.Count == this.QueryBuilder.JoinQueryInfos.Count+1) { return true; } } return this.QueryBuilder.JoinIndex == 0 && this.QueryBuilder.IsSqlQuery == false && !this.QueryBuilder.AsTables.Any() && this.QueryBuilder.IsSingle() && (this.QueryBuilder.WhereInfos.Any()|| this.QueryBuilder.SelectValue is Expression); } #endregion } }