SqlSugar/Src/Asp.NetCore2/SqlSugar/Abstract/QueryableProvider/QueryableHelper.cs
2023-05-12 17:22:39 +08:00

2158 lines
107 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
namespace SqlSugar
{
public partial class QueryableProvider<T> : QueryableAccessory, ISugarQueryable<T>
{
#region Tree
private List<T> _ToParentListByTreeKey(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue)
{
var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
var treeKey = entity.Columns.FirstOrDefault(it => it.IsTreeKey);
List<T> result = new List<T>() { };
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<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List<IConditionalModel>() {
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<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List<IConditionalModel>() {
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<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List<IConditionalModel>() {
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<T> _ToParentListByTreeKey(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression)
{
var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
var treeKey = entity.Columns.FirstOrDefault(it => it.IsTreeKey);
List<T> result = new List<T>() { };
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<T>().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List<IConditionalModel>() {
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<T>().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List<IConditionalModel>() {
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<T>().AS(tableName).WhereIF(parentWhereExpression != default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List<IConditionalModel>() {
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<List<T>> _ToParentListByTreeKeyAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue)
{
var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
var treeKey = entity.Columns.FirstOrDefault(it => it.IsTreeKey);
List<T> result = new List<T>() { };
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<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List<IConditionalModel>() {
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<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List<IConditionalModel>() {
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<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List<IConditionalModel>() {
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<List<T>> _ToParentListByTreeKeyAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression)
{
var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
var treeKey = entity.Columns.FirstOrDefault(it => it.IsTreeKey);
List<T> result = new List<T>() { };
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<T>().AS(tableName).WhereIF(parentWhereExpression!=default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List<IConditionalModel>() {
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<T>().AS(tableName).WhereIF(parentWhereExpression!=default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List<IConditionalModel>() {
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<T>().AS(tableName).WhereIF(parentWhereExpression!=default, parentWhereExpression).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List<IConditionalModel>() {
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<T> GetChildList(Expression<Func<T, object>> parentIdExpression, string pkName, List<T> 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<T> BuildChildList(List<T> 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<string, List<T>> fc = null;
fc = (rootVal) =>
{
var finalList = new List<T>();
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<object> GetPrentIds(List<T> list, object id, EntityColumnInfo pkName, EntityColumnInfo parentName)
{
var currentId = id;
List<object> result = new List<object>();
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<T> TreeAndFilterIds(Expression<Func<T, IEnumerable<object>>> childListExpression, Expression<Func<T, object>> parentIdExpression, object rootValue, object[] childIds, ref List<T> list)
{
var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
var pk = GetTreeKey(entity);
var pkColumn = entity.Columns.FirstOrDefault(z => z.PropertyName == pk);
var newIds = new List<object>();
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<T> GetTreeRoot(Expression<Func<T, IEnumerable<object>>> childListExpression, Expression<Func<T, object>> parentIdExpression, string pk, List<T> list, object rootValue)
{
var childName = ((childListExpression as LambdaExpression).Body as MemberExpression).Member.Name;
string parentIdName = GetParentName(parentIdExpression);
return BuildTree(list, pk, parentIdName, childName, rootValue)?.ToList() ?? default;
}
private static string GetParentName(Expression<Func<T, object>> 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;
}
private static IEnumerable<T> BuildTree(IEnumerable<T> list, string idName, string pIdName, string childName, object rootValue)
{
var type = typeof(T);
var mainIdProp = type.GetProperty(idName);
var pIdProp = type.GetProperty(pIdName);
var childProp = type.GetProperty(childName);
var kvList = list.ToDictionary(x => mainIdProp.GetValue(x).ObjToString());
var group = list.GroupBy(x => pIdProp.GetValue(x).ObjToString());
var root = rootValue != null ? group.FirstOrDefault(x => x.Key == rootValue.ObjToString()) : group.FirstOrDefault(x => x.Key == null || x.Key == "" || x.Key == "0" || x.Key == Guid.Empty.ToString());
if (root != null)
{
foreach (var item in group)
{
if (kvList.TryGetValue(item.Key, out var parent))
{
childProp.SetValue(parent, item.ToList());
}
}
}
return root;
}
public List<T> GetTreeChildList(List<T> 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<int> 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<TResult>(Expression expression)
{
QueryBuilder.CheckExpression(expression, "Main");
var isSingle = QueryBuilder.IsSingle();
var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple);
var result = Min<TResult>(lamResult.GetResultString());
QueryBuilder.SelectValue = null;
return result;
}
protected async Task<TResult> _MinAsync<TResult>(Expression expression)
{
QueryBuilder.CheckExpression(expression, "Main");
var isSingle = QueryBuilder.IsSingle();
var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple);
var result = await MinAsync<TResult>(lamResult.GetResultString());
QueryBuilder.SelectValue = null;
return result;
}
protected TResult _Avg<TResult>(Expression expression)
{
QueryBuilder.CheckExpression(expression, "Avg");
var isSingle = QueryBuilder.IsSingle();
var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple);
return Avg<TResult>(lamResult.GetResultString());
}
protected async Task<TResult> _AvgAsync<TResult>(Expression expression)
{
QueryBuilder.CheckExpression(expression, "Avg");
var isSingle = QueryBuilder.IsSingle();
var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple);
return await AvgAsync<TResult>(lamResult.GetResultString());
}
protected TResult _Max<TResult>(Expression expression)
{
QueryBuilder.CheckExpression(expression, "Max");
var isSingle = QueryBuilder.IsSingle();
var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple);
var reslut = Max<TResult>(lamResult.GetResultString());
QueryBuilder.SelectValue = null;
return reslut;
}
protected async Task<TResult> _MaxAsync<TResult>(Expression expression)
{
QueryBuilder.CheckExpression(expression, "Max");
var isSingle = QueryBuilder.IsSingle();
var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple);
var reslut = await MaxAsync<TResult>(lamResult.GetResultString());
QueryBuilder.SelectValue = null;
return reslut;
}
protected TResult _Sum<TResult>(Expression expression)
{
QueryBuilder.CheckExpression(expression, "Sum");
var isSingle = QueryBuilder.IsSingle();
var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple);
var reslut = Sum<TResult>(lamResult.GetResultString());
QueryBuilder.SelectValue = null;
return reslut;
}
protected async Task<TResult> _SumAsync<TResult>(Expression expression)
{
QueryBuilder.CheckExpression(expression, "Sum");
var isSingle = QueryBuilder.IsSingle();
var lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple);
var reslut = await SumAsync<TResult>(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<NavigatManager<T>>();
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 static void AddMappingNavProperties(Dictionary<string, Expression> dic, AppendNavInfo navInfo, List<EntityColumnInfo> entityColumns)
{
foreach (var item in dic)
{
var value = item.Value;
var expressionTree = new ExpressionTreeVisitor().GetExpressions(value);
var isSqlMethod = 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);
}
}
}
}
private static void AddAppendProperties(IEnumerable<NavigatManager<T>> navManages, AppendNavInfo navInfo, List<EntityColumnInfo> entityColumns, IEnumerable<EntityColumnInfo> pkColumns)
{
foreach (var item in pkColumns)
{
navInfo.AppendProperties.Add(item.PropertyName, item.DbColumnName);
}
foreach (var item in navManages)
{
var navName = ExpressionTool.GetMemberName(item.Expressions.First());
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 == name1);
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);
}
}
}
}
private async Task _InitNavigatAsync<TResult>(List<TResult> result)
{
if (this.QueryBuilder.Includes != null)
{
await Task.Run(() => { _InitNavigat(result); });
}
}
private void _InitNavigat<TResult>(List<TResult> result)
{
if (this.QueryBuilder.Includes != null)
{
var managers = (this.QueryBuilder.Includes as List<object>);
if (IsSelectNavQuery())
{
if (result.HasValue())
{
SelectNavQuery(result, managers);
}
}
else
{
foreach (var it in managers)
{
var manager = it as NavigatManager<TResult>;
manager.RootList = result;
manager.Execute();
}
}
}
}
private void SelectNavQuery<TResult>(List<TResult> result, List<object> managers)
{
if (result.Any())
{
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);
var outList = SelectNavQuery_SetList(result, it, p, tType, columns, listType);
it.GetType().GetMethod("Execute").Invoke(it, null);
SelectNavQuery_MappingList(it, result, outList, allColumns.Where(a => a.Navigat != null).ToList());
}
}
}
private void SelectNavQuery_MappingList<TResult>(object it,List<TResult> result, IList outList,List<EntityColumnInfo> 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 rightValue=rightColumnInfo.PropertyInfo.GetValue(rightObject);
var leftName = item.Key;
//// 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<Func<X, List<int>>>(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<TResult>(List<TResult> result, object it, PropertyInfo p, Type tType, List<EntityColumnInfo> 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
{
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<TResult>(List<TResult> 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<T>)Convert.ChangeType(result, typeof(List<T>));
var mapperCache = new MapperCache<T>(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<T> _Mapper<TObject>(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<TObject>), ".Mapper() parameter error");
if (objType == typeof(List<TObject>))
{
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<Action<List<T>>>();
if (isSelf)
{
Action<List<T>> 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<string> 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<IConditionalModel> wheres = new List<IConditionalModel>()
{
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<TObject>().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<List<T>> mapper = (entitys) =>
{
if (entitys.IsNullOrEmpty() || !entitys.Any()) return;
var entity = entitys.First();
var tEntity = this.Context.EntityMaintenance.GetEntityInfo<T>();
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<string> 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<IConditionalModel> wheres = new List<IConditionalModel>()
{
new ConditionalModel()
{
FieldName=dbColumnName,
ConditionalType= ConditionalType.In,
FieldValue=string.Join(",",inValues)
}
};
var list = this.Context.Queryable<TObject>().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<T> _Mapper<TObject>(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<TObject>), ".Mapper() parameter error");
if (objType == typeof(List<TObject>))
{
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<Action<List<T>>>();
if (isSelf)
{
Action<List<T>> 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<string> inValues = entitys.Select(it => it.GetType().GetProperty(mainFiledName).GetValue(it, null).ObjToString()).ToList();
List<IConditionalModel> wheres = new List<IConditionalModel>()
{
new ConditionalModel()
{
FieldName=whereCol.DbColumnName,
ConditionalType= ConditionalType.In,
FieldValue=string.Join(",",inValues.Distinct())
}
};
var list = this.Context.Queryable<TObject>().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<List<T>> mapper = (entitys) =>
{
if (entitys.IsNullOrEmpty() || !entitys.Any()) return;
var entity = entitys.First();
var tEntity = this.Context.EntityMaintenance.GetEntityInfo<T>();
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<string> 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<IConditionalModel> wheres = new List<IConditionalModel>()
{
new ConditionalModel()
{
FieldName=dbColumnName,
ConditionalType= ConditionalType.In,
FieldValue=string.Join(",",inValues)
}
};
var list = this.Context.Queryable<TObject>().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<TResult>(List<TResult> 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 string GetTableName(EntityInfo entity, string tableName)
{
var oldTableName = tableName;
var attr = entity?.Type?.GetCustomAttribute<TenantAttribute>();
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;
tableName = this.QueryBuilder.LambdaExpressions.DbMehtods.GetTableWithDataBase
(this.QueryBuilder.Builder.GetTranslationColumnName(dbName), this.QueryBuilder.Builder.GetTranslationColumnName(tableName));
}
var dbLinkName = this.Context.CurrentConnectionConfig.DbLinkName;
if (dbLinkName.HasValue())
{
tableName = dbLinkName+"."+this.QueryBuilder.Builder.GetTranslationColumnName(oldTableName);
}
return tableName;
}
protected string AppendSelect(List<EntityColumnInfo> entityColumnInfos,string sql, ReadOnlyCollection<ParameterExpression> parameters, List<EntityColumnInfo> 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<EntityColumnInfo> entityColumnInfos, string sql, ReadOnlyCollection<ParameterExpression> parameters, List<EntityColumnInfo> columnsResult, int parameterIndex1)
{
var list = ExpressionTool.GetMemberInit(this.QueryBuilder.SelectValue).Bindings.Cast<MemberBinding>()
.Select(it => it.Member.Name).ToList();
var columns = entityColumnInfos;
var parameterName = parameters[parameterIndex1];
if (this.QueryBuilder.AutoAppendedColumns == null)
{
this.QueryBuilder.AutoAppendedColumns = new List<string>();
}
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)))
{
sql = $" {sql},{SqlBuilder.GetTranslationColumnName(item.DbColumnName)} AS {SqlBuilder.GetTranslationColumnName(item.PropertyName)} ";
this.QueryBuilder.AutoAppendedColumns.Add(item.PropertyName);
}
}
return sql;
}
protected string AppendSelect<EntityType>(string sql, ReadOnlyCollection<ParameterExpression> parameters, List<EntityColumnInfo> columnsResult, int parameterIndex1)
{
var columns = this.Context.EntityMaintenance.GetEntityInfo<EntityType>().Columns;
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()))
{
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 = this.Context.EntityMaintenance.GetTableName(lastPareamter.Type)
};
if (QueryBuilder.IsCrossQueryWithAttr)
{
result.TableName=GetTableName(this.Context.EntityMaintenance.GetEntityInfo(lastPareamter.Type), result.TableName);
}
if (this.Context.CurrentConnectionConfig?.MoreSettings?.PgSqlIsAutoToLower == false)
{
result.ShortName = this.SqlBuilder.GetTranslationColumnName(result.ShortName);
}
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)
{
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, @"^\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<TResult> _Select<TResult>(Expression expression)
{
QueryBuilder.CheckExpression(expression, "Select");
this.Context.InitMappingInfo(typeof(TResult));
var result = InstanceFactory.GetQueryable<TResult>(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<T> _OrderBy(Expression expression, OrderByType type = OrderByType.Asc)
{
QueryBuilder.CheckExpression(expression, "OrderBy");
var isSingle = QueryBuilder.IsSingle();
if (expression.ToString().IsContainsIn("Desc(", "Asc("))
{
var orderValue = "";
var newExp = (expression as LambdaExpression).Body as NewExpression;
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<T> _GroupBy(Expression expression)
{
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
{
lamResult = QueryBuilder.GetExpressionValue(expression, isSingle ? ResolveExpressType.FieldSingle : ResolveExpressType.FieldMultiple);
result = lamResult.GetResultString();
}
GroupBy(result);
return this;
}
protected ISugarQueryable<T> _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.GeFilterList.HasValue() && FilterName.HasValue())
{
var list = this.Context.QueryFilter.GeFilterList.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<T> _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<T> _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<TResult> _ToList<TResult>()
{
List<TResult> result = null;
var sqlObj = this._ToSql();
if (IsCache)
{
var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService;
result = CacheSchemeMain.GetOrCreate<List<TResult>>(cacheService, this.QueryBuilder, () => { return GetData<TResult>(sqlObj); }, CacheTime, this.Context, CacheKey);
}
else
{
result = GetData<TResult>(sqlObj);
}
RestoreMapping();
_InitNavigat(result);
_SubQuery(result);
_Mapper(result);
return result;
}
protected async Task<List<TResult>> _ToListAsync<TResult>()
{
List<TResult> result = null;
var sqlObj = this._ToSql();
if (IsCache)
{
var cacheService = this.Context.CurrentConnectionConfig.ConfigureExternalServices.DataInfoCacheService;
result = CacheSchemeMain.GetOrCreate<List<TResult>>(cacheService, this.QueryBuilder, () => { return GetData<TResult>(sqlObj); }, CacheTime, this.Context, CacheKey);
}
else
{
result = await GetDataAsync<TResult>(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))
{
this.With(SqlWith.NoLock);
}
}
protected List<TResult> GetData<TResult>(KeyValuePair<string, List<SugarParameter>> sqlObj)
{
List<TResult> result;
var isComplexModel = QueryBuilder.IsComplexModel(sqlObj.Key);
var entityType = typeof(TResult);
bool isChangeQueryableSlave = GetIsSlaveQuery();
bool isChangeQueryableMasterSlave = GetIsMasterQuery();
var dataReader = this.Db.GetDataReader(sqlObj.Key, sqlObj.Value.ToArray());
result = GetData<TResult>(isComplexModel, entityType, dataReader);
RestChangeMasterQuery(isChangeQueryableMasterSlave);
RestChangeSlaveQuery(isChangeQueryableSlave);
return result;
}
protected async Task<List<TResult>> GetDataAsync<TResult>(KeyValuePair<string, List<SugarParameter>> sqlObj)
{
List<TResult> result;
var isComplexModel = QueryBuilder.IsComplexModel(sqlObj.Key);
var entityType = typeof(TResult);
bool isChangeQueryableSlave = GetIsSlaveQuery();
bool isChangeQueryableMasterSlave = GetIsMasterQuery();
var dataReader = await this.Db.GetDataReaderAsync(sqlObj.Key, sqlObj.Value.ToArray());
result = await GetDataAsync<TResult>(isComplexModel, entityType, dataReader);
RestChangeMasterQuery(isChangeQueryableMasterSlave);
RestChangeSlaveQuery(isChangeQueryableSlave);
return result;
}
private List<TResult> GetData<TResult>(bool isComplexModel, Type entityType, IDataReader dataReader)
{
List<TResult> result;
this.Bind.QueryBuilder = this.QueryBuilder;
this.Context.Utilities.QueryBuilder = this.QueryBuilder;
if (entityType == UtilConstants.DynamicType)
{
result = this.Context.Utilities.DataReaderToExpandoObjectList(dataReader) as List<TResult>;
}
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<TResult>(dataReader);
}
else if (QueryBuilder.IsSelectSingleFiledArray)
{
result = this.Context.Utilities.DataReaderToSelectArrayList<TResult>(dataReader);
}
else if (entityType.IsAnonymousType() || isComplexModel)
{
result = this.Context.Utilities.DataReaderToList<TResult>(dataReader);
}
else
{
result = this.Bind.DataReaderToList<TResult>(entityType, dataReader);
}
SetContextModel(result, entityType);
return result;
}
private async Task<List<TResult>> GetDataAsync<TResult>(bool isComplexModel, Type entityType, IDataReader dataReader)
{
List<TResult> 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<TResult>;
}
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<TResult>(dataReader);
}
else if (QueryBuilder.IsSelectSingleFiledArray)
{
result =await this.Context.Utilities.DataReaderToSelectArrayListAsync<TResult>(dataReader);
}
else if (entityType.IsAnonymousType() || isComplexModel)
{
result = await this.Context.Utilities.DataReaderToListAsync<TResult>(dataReader);
}
else
{
result = await this.Bind.DataReaderToListAsync<TResult>(entityType, dataReader);
}
SetContextModel(result, entityType);
return result;
}
protected void _InQueryable(Expression expression, KeyValuePair<string, List<SugarParameter>> 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<string> 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<string> 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<SugarParameter>();
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,
_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.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();
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<string, List<SugarParameter>> _ToSql()
{
InitMapping();
ToSqlBefore();
string sql = QueryBuilder.ToSqlString();
RestoreMapping();
return new KeyValuePair<string, List<SugarParameter>>(sql, QueryBuilder.Parameters);
}
#endregion
#region Subquery
private bool IsSubToList()
{
return this.QueryBuilder.SubToListParameters != null && this.QueryBuilder.SubToListParameters.Count > 0;
}
public virtual ISugarQueryable<T> 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<T>().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<T> 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<T>().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<TResult>(List<TResult> 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<TResult>(List<TResult> result, List<List<QueryableAppendColumn>> appendValues, KeyValuePair<string, object> 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<object>().FirstOrDefault());
result[i] = jobj.ToObject<TResult>();
}
else
{
var jobj = JObject.FromObject(item);
var prop = jobj.Property(itemProperty.Name);
prop.Value = JArray.FromObject(subList);
result[i] = jobj.ToObject<TResult>();
}
}
else
{
if (isFirst)
{
itemProperty.SetValue(item, (subList as IList)[0] );
}
else
{
itemProperty.SetValue(item, subList);
}
}
}
}
private void AppendSubWhereToList<TResult>(List<TResult> result, List<List<QueryableAppendColumn>> appendValues, KeyValuePair<string, object> subPara)
{
var ps = this.QueryBuilder.Parameters;
var index = 0;
List<string> sqls = new List<string>();
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<QueryableAppendColumn>() {
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<object>().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<TResult>(List<TResult> result, PropertyInfo itemProperty, List<List<QueryableAppendColumn>> appendValue, List<object> 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<TResult>();
//itemProperty.SetValue(item, setValue);
}
return resIndex;
}
private static int SetSubListWithAnonymousTypeFirst<TResult>(List<TResult> result, PropertyInfo itemProperty, List<List<QueryableAppendColumn>> appendValue, List<object> 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<TResult>();
//itemProperty.SetValue(item, setValue);
}
return resIndex;
}
private static int SetSubListWithClassFirst<TResult>(List<TResult> result, PropertyInfo itemProperty, List<List<QueryableAppendColumn>> appendValue, List<object> 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<TResult>(List<TResult> result, PropertyInfo itemProperty, List<List<QueryableAppendColumn>> appendValue, List<object> 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;
}
setValue.Add(addItem);
}
appindex++;
}
}
itemProperty.SetValue(item, setValue);
resIndex++;
}
return resIndex;
}
private async Task _SubQueryAsync<TResult>(List<TResult> result)
{
var isSubToList = this.QueryBuilder.SubToListParameters != null && this.QueryBuilder.SubToListParameters.Any();
if (!isSubToList)
{
return;
}
await Task.Run(() =>{_SubQuery(result);});
}
public List<Type> SubQueryList<Type>(string sql,object parameters)
{
return this.Context.Ado.SqlQuery<Type>(sql,parameters);
}
#endregion
#region Bool
private bool MasterHasWhereFirstJoin()
{
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
}
}