mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-05-04 04:37:58 +08:00
2158 lines
107 KiB
C#
2158 lines
107 KiB
C#
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
|
||
}
|
||
}
|