Files
SqlSugar/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/NavigatManager.cs

741 lines
40 KiB
C#
Raw Normal View History

2022-04-11 14:04:22 +08:00
using System;
2022-04-11 20:54:20 +08:00
using System.Collections;
2022-04-11 14:04:22 +08:00
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace SqlSugar
{
public class NavigatManager<T>
{
public SqlSugarProvider Context { get; set; }
2022-04-11 20:54:20 +08:00
public Func<ISugarQueryable<object>, List<object>> SelectR1 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR2 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR3 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR4 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR5 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR6 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR7 { get; set; }
public Func<ISugarQueryable<object>, List<object>> SelectR8 { get; set; }
2022-04-11 14:04:22 +08:00
public Expression[] Expressions { get; set; }
public List<T> RootList { get; set; }
//public QueryableProvider<T> Queryable { get; set; }
2022-04-11 21:19:51 +08:00
private List<Expression> _preExpressionList = new List<Expression>();
2022-04-12 01:30:21 +08:00
private List<object> _preList = new List<object>();
2022-04-13 20:50:17 +08:00
private List<Expression> _ListCallFunc;
2022-04-11 14:04:22 +08:00
//private Expression[] _expressions;
//private List<T> _list;
//private EntityInfo _entityInfo;
public void Execute()
{
2022-04-11 20:54:20 +08:00
var i = 1;
foreach (var item in Expressions)
2022-04-11 14:04:22 +08:00
{
2022-04-11 20:54:20 +08:00
ExecuteByLay(i, item);
i++;
}
}
2022-04-11 14:04:22 +08:00
2022-04-11 20:54:20 +08:00
private void ExecuteByLay(int i, Expression item)
{
2022-04-13 20:50:17 +08:00
_ListCallFunc = GetWhereExpression(ref item);
2022-04-11 20:54:20 +08:00
if (i == 1)
{
ExecuteByLay(item, RootList.Select(it => it as object).ToList(), SelectR1);
2022-04-11 14:04:22 +08:00
}
2022-04-12 00:14:35 +08:00
else if (i == 2)
2022-04-11 21:19:51 +08:00
{
2022-04-12 01:30:21 +08:00
var currentList = RootList;
if (RootList == null || currentList.Count == 0) return;
2022-04-11 21:19:51 +08:00
var memberExpression = ((_preExpressionList.Last() as LambdaExpression).Body as MemberExpression);
var navObjectName = memberExpression.Member.Name;
2022-04-12 01:30:21 +08:00
var navType = currentList[0].GetType().GetProperty(navObjectName).PropertyType.Name;
var isList = navType.StartsWith("List`");
List<object> list = new List<object>();
if (isList)
{
2022-04-21 17:01:38 +08:00
list = currentList.SelectMany(it => (it.GetType().GetProperty(navObjectName).GetValue(it) as IList)?.Cast<object>()??new List<object> { }).ToList();
2022-04-12 01:30:21 +08:00
}
else
{
list = currentList.Select(it => (it.GetType().GetProperty(navObjectName).GetValue(it))).ToList();
}
2022-04-11 21:19:51 +08:00
ExecuteByLay(item, list, SelectR2);
2022-04-12 01:30:21 +08:00
_preList = list;
}
else if (i == 3)
{
2022-04-12 01:43:08 +08:00
var currentList = _preList.Where(it => it != null).ToList();
2022-04-12 01:30:21 +08:00
if (RootList == null || currentList.Count == 0) return;
2022-04-15 14:58:18 +08:00
List<object> list = ExecuteByLay(currentList);
2022-04-12 01:30:21 +08:00
ExecuteByLay(item, list, SelectR3);
2022-04-12 01:43:08 +08:00
_preList = list.ToList();
2022-04-11 21:19:51 +08:00
}
2022-04-15 14:59:25 +08:00
else if (i == 4)
{
var currentList = _preList.Where(it => it != null).ToList();
if (RootList == null || currentList.Count == 0) return;
List<object> list = ExecuteByLay(currentList);
ExecuteByLay(item, list, SelectR4);
_preList = list.ToList();
}
else if (i == 5)
{
var currentList = _preList.Where(it => it != null).ToList();
if (RootList == null || currentList.Count == 0) return;
List<object> list = ExecuteByLay(currentList);
ExecuteByLay(item, list, SelectR5);
_preList = list.ToList();
}
else if (i == 6)
{
var currentList = _preList.Where(it => it != null).ToList();
if (RootList == null || currentList.Count == 0) return;
List<object> list = ExecuteByLay(currentList);
ExecuteByLay(item, list, SelectR6);
_preList = list.ToList();
}
else if (i == 7)
{
var currentList = _preList.Where(it => it != null).ToList();
if (RootList == null || currentList.Count == 0) return;
List<object> list = ExecuteByLay(currentList);
ExecuteByLay(item, list, SelectR7);
_preList = list.ToList();
}
2022-04-11 21:19:51 +08:00
_preExpressionList.Add(item);
2022-04-13 20:50:17 +08:00
_ListCallFunc = new List<Expression>();
2022-04-11 14:04:22 +08:00
}
2022-04-15 14:58:18 +08:00
private List<object> ExecuteByLay(List<object> currentList)
{
var memberExpression = ((_preExpressionList.Last() as LambdaExpression).Body as MemberExpression);
var navObjectName = memberExpression.Member.Name;
var navType = currentList[0].GetType().GetProperty(navObjectName).PropertyType.Name;
var isList = navType.StartsWith("List`");
List<object> list = new List<object>();
if (isList)
{
2022-05-24 09:42:56 +08:00
list = currentList.Where(it=> it.GetType().GetProperty(navObjectName).GetValue(it)!=null).SelectMany(it => (it.GetType().GetProperty(navObjectName).GetValue(it) as IList).Cast<object>()).ToList();
2022-04-15 14:58:18 +08:00
}
else
{
2022-05-24 09:42:56 +08:00
list = currentList.Where(it=>it.GetType().GetProperty(navObjectName).GetValue(it)!=null).Select(it => (it.GetType().GetProperty(navObjectName).GetValue(it))).ToList();
2022-04-15 14:58:18 +08:00
}
return list;
}
2022-04-11 20:54:20 +08:00
private void ExecuteByLay(Expression expression, List<object> list, Func<ISugarQueryable<object>, List<object>> selector)
{
if (list == null || list.Count == 0) return;
2022-04-12 01:30:21 +08:00
list = list.Where(it => it != null).ToList();
2022-04-11 20:54:20 +08:00
var memberExpression = ((expression as LambdaExpression).Body as MemberExpression);
2022-04-12 01:30:21 +08:00
var listItemType = list.Where(it=>it!=null).FirstOrDefault()?.GetType();
2022-07-15 18:32:31 +08:00
if (listItemType == null)
{
return;
}
2022-04-12 01:30:21 +08:00
if (listItemType.Name.StartsWith("List`"))
{
listItemType = listItemType.GetGenericArguments()[0];
}
2022-07-15 18:32:31 +08:00
//if (listItemType == null) return;
2022-04-12 01:30:21 +08:00
2022-04-11 20:54:20 +08:00
var listItemEntity = this.Context.EntityMaintenance.GetEntityInfo(listItemType);
var listPkColumn = listItemEntity.Columns.Where(it => it.IsPrimarykey).FirstOrDefault();
var navObjectName = memberExpression.Member.Name;
var navObjectNamePropety = listItemType.GetProperty(navObjectName);
var navObjectNameColumnInfo = listItemEntity.Columns.First(it => it.PropertyName == navObjectName);
Check.ExceptionEasy(navObjectNameColumnInfo.Navigat == null, $"{navObjectName} not [Navigat(..)] ", $"{navObjectName} 没有导航特性 [Navigat(..)] ");
2022-04-14 12:53:53 +08:00
if (navObjectNameColumnInfo.Navigat.NavigatType == NavigateType.OneToOne)
2022-04-11 20:54:20 +08:00
{
OneToOne(list, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo);
}
2022-04-14 12:53:53 +08:00
else if (navObjectNameColumnInfo.Navigat.NavigatType == NavigateType.OneToMany)
2022-04-11 20:54:20 +08:00
{
OneToMany(list, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo);
}
2022-04-14 12:53:53 +08:00
else if (navObjectNameColumnInfo.Navigat.NavigatType == NavigateType.ManyToOne)
2022-04-11 20:54:20 +08:00
{
2022-04-12 00:27:34 +08:00
OneToOne(list, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo);
2022-04-11 20:54:20 +08:00
}
2022-04-29 18:50:48 +08:00
else if (navObjectNameColumnInfo.Navigat.NavigatType == NavigateType.Dynamic)
{
2022-05-21 01:01:31 +08:00
Dynamic(list, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo,expression);
2022-04-29 18:50:48 +08:00
}
2022-04-11 20:54:20 +08:00
else
{
2022-04-11 21:19:51 +08:00
ManyToMany(list, selector, listItemEntity, navObjectNamePropety, navObjectNameColumnInfo);
2022-04-11 20:54:20 +08:00
}
}
2022-04-13 20:50:17 +08:00
private List<Expression> GetWhereExpression(ref Expression expression)
{
List<Expression> expressions = new List<Expression>();
var isCall = (expression as LambdaExpression).Body is MethodCallExpression;
if (isCall)
{
var newexp = (expression as LambdaExpression).Body;
while (newexp is MethodCallExpression)
{
expressions.Add(newexp);
newexp= (newexp as MethodCallExpression).Arguments[0];
}
expression =LambdaExpression.Lambda(newexp);
}
return expressions;
}
2022-04-11 21:19:51 +08:00
private void ManyToMany(List<object> list, Func<ISugarQueryable<object>, List<object>> selector, EntityInfo listItemEntity, System.Reflection.PropertyInfo navObjectNamePropety, EntityColumnInfo navObjectNameColumnInfo)
{
2022-04-11 22:38:53 +08:00
var bEntity = navObjectNameColumnInfo.PropertyInfo.PropertyType.GetGenericArguments()[0];
var bEntityInfo = this.Context.EntityMaintenance.GetEntityInfo(bEntity);
2022-04-12 00:27:34 +08:00
var bPkColumn = bEntityInfo.Columns.FirstOrDefault(it => it.IsPrimarykey);
2022-05-06 17:22:23 +08:00
this.Context.InitMappingInfo(bEntity);
2022-04-11 22:38:53 +08:00
var listItemPkColumn = listItemEntity.Columns.Where(it => it.IsPrimarykey).FirstOrDefault();
var ids = list.Select(it => it.GetType().GetProperty(listItemPkColumn.PropertyName).GetValue(it)).Select(it => it == null ? "null" : it).Distinct().ToList();
var mappingEntity = this.Context.EntityMaintenance.GetEntityInfo(navObjectNameColumnInfo.Navigat.MappingType);
var aColumn = mappingEntity.Columns.First(it => it.PropertyName == navObjectNameColumnInfo.Navigat.MappingAId);
var bColumn = mappingEntity.Columns.First(it => it.PropertyName == navObjectNameColumnInfo.Navigat.MappingBId);
List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
conditionalModels.Add((new ConditionalModel()
{
ConditionalType = ConditionalType.In,
FieldName = aColumn.DbColumnName,
FieldValue = String.Join(",", ids),
2022-04-12 00:14:35 +08:00
CSharpTypeName = aColumn.PropertyInfo.PropertyType.Name
2022-04-11 22:38:53 +08:00
}));
2022-09-06 12:54:33 +08:00
var queryable = this.Context.Queryable<object>();
var abids = queryable.AS(mappingEntity.DbTableName).Filter(mappingEntity.Type).Where(conditionalModels).Select<SugarAbMapping>($"{queryable.SqlBuilder.GetTranslationColumnName(aColumn.DbColumnName)} as aid,{queryable.SqlBuilder.GetTranslationColumnName(bColumn.DbColumnName)} as bid").ToList();
2022-04-11 22:38:53 +08:00
List<IConditionalModel> conditionalModels2 = new List<IConditionalModel>();
conditionalModels2.Add((new ConditionalModel()
{
ConditionalType = ConditionalType.In,
2022-04-12 00:27:34 +08:00
FieldName = bPkColumn.DbColumnName,
2022-04-12 00:14:35 +08:00
FieldValue = String.Join(",", abids.Select(it => it.Bid).ToArray()),
2022-04-11 22:38:53 +08:00
CSharpTypeName = bColumn.PropertyInfo.PropertyType.Name
}));
2022-04-13 20:50:17 +08:00
var sql = GetWhereSql();
2022-07-13 17:58:42 +08:00
var bList = selector(this.Context.Queryable<object>().AS(bEntityInfo.DbTableName).Filter(bEntityInfo.Type).AddParameters(sql.Parameters).Where(conditionalModels2).WhereIF(sql.WhereString.HasValue(),sql.WhereString).Select(sql.SelectString).OrderByIF(sql.OrderByString.HasValue(),sql.OrderByString));
2022-04-12 00:27:34 +08:00
if (bList.HasValue())
2022-04-11 22:38:53 +08:00
{
2022-04-12 00:27:34 +08:00
foreach (var listItem in list)
2022-04-11 22:38:53 +08:00
{
2022-04-18 12:04:35 +08:00
if (navObjectNamePropety.GetValue(listItem) == null)
2022-04-11 22:38:53 +08:00
{
2022-04-18 12:04:35 +08:00
var instance = Activator.CreateInstance(navObjectNamePropety.PropertyType, true);
var ilist = instance as IList;
foreach (var bInfo in bList)
2022-04-12 00:14:35 +08:00
{
2022-04-18 12:04:35 +08:00
var pk = listItemPkColumn.PropertyInfo.GetValue(listItem).ObjToString();
var bid = bPkColumn.PropertyInfo.GetValue(bInfo).ObjToString();
if (abids.Any(x => x.Aid == pk && x.Bid == bid))
{
2022-04-12 00:27:34 +08:00
ilist.Add(bInfo);
2022-04-18 12:04:35 +08:00
}
2022-04-12 00:14:35 +08:00
}
2022-04-29 23:30:03 +08:00
if (sql.MappingExpressions.HasValue())
{
MappingFieldsHelper<T> helper = new MappingFieldsHelper<T>();
2022-05-05 09:13:59 +08:00
helper.Context = this.Context;
2022-04-29 23:30:03 +08:00
helper.NavEntity = bEntityInfo;
helper.RootEntity = this.Context.EntityMaintenance.GetEntityInfo<T>();
helper.SetChildList(navObjectNameColumnInfo, listItem, ilist.Cast<object>().ToList(), sql.MappingExpressions);
}
else
{
2022-06-07 19:15:39 +08:00
if (sql.Skip != null || sql.Take != null)
{
var instanceCast = (instance as IList);
var newinstance = Activator.CreateInstance(navObjectNamePropety.PropertyType, true) as IList;
SkipTakeIList(sql, instanceCast, newinstance);
navObjectNamePropety.SetValue(listItem, newinstance);
}
else
{
navObjectNamePropety.SetValue(listItem, instance);
}
2022-04-29 23:30:03 +08:00
}
2022-04-11 22:38:53 +08:00
}
}
}
2022-07-10 12:42:15 +08:00
else
{
foreach (var listItem in list)
{
if (navObjectNamePropety.GetValue(listItem) == null)
{
var newinstance = Activator.CreateInstance(navObjectNamePropety.PropertyType, true) as IList;
navObjectNamePropety.SetValue(listItem,newinstance);
}
}
}
2022-04-11 21:19:51 +08:00
}
2022-06-07 19:15:39 +08:00
private static void SkipTakeIList(SqlInfo sql, IList instanceCast, IList newinstance)
{
var intArray = Enumerable.Range(0, instanceCast.Count);
if (sql.Skip != null)
{
intArray = intArray
.Skip(sql.Skip.Value);
}
if (sql.Take != null)
{
intArray = intArray
.Take(sql.Take.Value);
}
foreach (var i in intArray)
{
newinstance.Add(instanceCast[i]);
}
}
2022-04-11 20:54:20 +08:00
private void OneToOne(List<object> list, Func<ISugarQueryable<object>, List<object>> selector, EntityInfo listItemEntity, System.Reflection.PropertyInfo navObjectNamePropety, EntityColumnInfo navObjectNameColumnInfo)
{
var navColumn = listItemEntity.Columns.FirstOrDefault(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name);
2022-06-15 14:16:31 +08:00
Check.ExceptionEasy(navColumn == null, "OneToOne navigation configuration error", $"OneToOne导航配置错误 实体{ listItemEntity.EntityName } 不存在{navObjectNameColumnInfo.Navigat.Name}");
2022-04-11 20:54:20 +08:00
var navType = navObjectNamePropety.PropertyType;
var navEntityInfo = this.Context.EntityMaintenance.GetEntityInfo(navType);
2022-05-06 17:22:23 +08:00
this.Context.InitMappingInfo(navEntityInfo.Type);
2022-04-11 20:54:20 +08:00
var navPkColumn = navEntityInfo.Columns.Where(it => it.IsPrimarykey).FirstOrDefault();
2022-06-27 21:31:27 +08:00
Check.ExceptionEasy(navPkColumn==null&& navObjectNameColumnInfo.Navigat.Name2==null, navEntityInfo.EntityName+ "need primarykey", navEntityInfo.EntityName + " 需要主键");
2022-06-29 14:01:19 +08:00
if (navObjectNameColumnInfo.Navigat.Name2.HasValue())
2022-06-27 21:31:27 +08:00
{
navPkColumn = navEntityInfo.Columns.Where(it => it.PropertyName== navObjectNameColumnInfo.Navigat.Name2).FirstOrDefault();
}
2022-04-11 20:54:20 +08:00
var ids = list.Select(it => it.GetType().GetProperty(navObjectNameColumnInfo.Navigat.Name).GetValue(it)).Select(it => it == null ? "null" : it).Distinct().ToList();
List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
conditionalModels.Add((new ConditionalModel()
{
ConditionalType = ConditionalType.In,
FieldName = navPkColumn.DbColumnName,
FieldValue = String.Join(",", ids),
CSharpTypeName = navObjectNameColumnInfo.PropertyInfo.PropertyType.Name
}));
2022-04-19 13:24:48 +08:00
if (list.Any()&&navObjectNamePropety.GetValue(list.First()) == null)
2022-04-11 20:54:20 +08:00
{
2022-07-09 18:03:18 +08:00
var sqlObj = GetWhereSql(navObjectNameColumnInfo.Navigat.Name);
var navList = selector(this.Context.Queryable<object>().AS(navEntityInfo.DbTableName)
2022-08-05 23:55:14 +08:00
.WhereIF(navObjectNameColumnInfo.Navigat.WhereSql.HasValue(), navObjectNameColumnInfo.Navigat.WhereSql)
2022-07-09 18:03:18 +08:00
.WhereIF(sqlObj.WhereString.HasValue(),sqlObj.WhereString)
.AddParameters(sqlObj.Parameters).Where(conditionalModels));
2022-05-21 00:46:43 +08:00
var groupQuery = (from l in list
2022-05-13 14:10:07 +08:00
join n in navList
on navColumn.PropertyInfo.GetValue(l).ObjToString()
equals navPkColumn.PropertyInfo.GetValue(n).ObjToString()
select new
{
l,
n
}).ToList();
2022-05-21 00:46:43 +08:00
foreach (var item in groupQuery)
2022-05-13 14:10:07 +08:00
{
2022-08-04 13:16:44 +08:00
// var setValue = navList.FirstOrDefault(x => navPkColumn.PropertyInfo.GetValue(x).ObjToString() == navColumn.PropertyInfo.GetValue(item).ObjToString());
if (navObjectNamePropety.GetValue(item.l) == null)
{
navObjectNamePropety.SetValue(item.l, item.n);
}
else
{
//The reserved
}
2022-04-19 13:24:48 +08:00
2022-04-18 12:04:35 +08:00
}
2022-04-11 20:54:20 +08:00
}
}
private void OneToMany(List<object> list, Func<ISugarQueryable<object>, List<object>> selector, EntityInfo listItemEntity, System.Reflection.PropertyInfo navObjectNamePropety, EntityColumnInfo navObjectNameColumnInfo)
{
var navEntity = navObjectNameColumnInfo.PropertyInfo.PropertyType.GetGenericArguments()[0];
var navEntityInfo = this.Context.EntityMaintenance.GetEntityInfo(navEntity);
2022-05-06 17:22:23 +08:00
this.Context.InitMappingInfo(navEntityInfo.Type);
2022-04-11 20:54:20 +08:00
var navColumn = navEntityInfo.Columns.FirstOrDefault(it => it.PropertyName == navObjectNameColumnInfo.Navigat.Name);
2022-04-16 00:31:52 +08:00
Check.ExceptionEasy(navColumn == null, $"{navEntityInfo.EntityName} not found {navObjectNameColumnInfo.Navigat.Name} ", $"实体 {navEntityInfo.EntityName} 未找到导航配置列 {navObjectNameColumnInfo.Navigat.Name} ");
2022-04-11 20:54:20 +08:00
//var navType = navObjectNamePropety.PropertyType;
var listItemPkColumn = listItemEntity.Columns.Where(it => it.IsPrimarykey).FirstOrDefault();
2022-06-27 21:58:46 +08:00
Check.ExceptionEasy(listItemPkColumn == null&& navObjectNameColumnInfo.Navigat.Name2==null, listItemEntity.EntityName + " not primary key", listItemEntity.EntityName + "没有主键");
2022-06-29 14:01:19 +08:00
if (navObjectNameColumnInfo.Navigat.Name2.HasValue())
2022-06-27 21:58:46 +08:00
{
listItemPkColumn = listItemEntity.Columns.Where(it => it.PropertyName== navObjectNameColumnInfo.Navigat.Name2).FirstOrDefault();
}
2022-04-11 20:54:20 +08:00
var ids = list.Select(it => it.GetType().GetProperty(listItemPkColumn.PropertyName).GetValue(it)).Select(it => it == null ? "null" : it).Distinct().ToList();
List<IConditionalModel> conditionalModels = new List<IConditionalModel>();
conditionalModels.Add((new ConditionalModel()
{
ConditionalType = ConditionalType.In,
2022-04-13 22:01:14 +08:00
FieldName = navColumn.DbColumnName,
2022-04-11 20:54:20 +08:00
FieldValue = String.Join(",", ids),
CSharpTypeName = listItemPkColumn.PropertyInfo.PropertyType.Name
}));
2022-04-19 19:44:28 +08:00
var sqlObj = GetWhereSql(navObjectNameColumnInfo.Navigat.Name);
2022-04-19 13:24:48 +08:00
if (list.Any() && navObjectNamePropety.GetValue(list.First()) == null)
2022-04-11 21:19:51 +08:00
{
2022-07-23 14:12:03 +08:00
var navList = selector(this.Context.Queryable<object>(sqlObj.TableShortName).AS(navEntityInfo.DbTableName).Filter(navEntityInfo.Type).AddParameters(sqlObj.Parameters).Where(conditionalModels).WhereIF(sqlObj.WhereString.HasValue(), sqlObj.WhereString).Select(sqlObj.SelectString).OrderByIF(sqlObj.OrderByString.HasValue(), sqlObj.OrderByString));
2022-04-19 13:24:48 +08:00
if (navList.HasValue())
2022-04-11 20:54:20 +08:00
{
2022-05-13 16:31:21 +08:00
//var setValue = navList
// .Where(x => navColumn.PropertyInfo.GetValue(x).ObjToString() == listItemPkColumn.PropertyInfo.GetValue(item).ObjToString()).ToList();
2022-06-09 19:51:48 +08:00
var groupQuery = (from l in list.Distinct()
2022-05-13 16:31:21 +08:00
join n in navList
on listItemPkColumn.PropertyInfo.GetValue(l).ObjToString()
equals navColumn.PropertyInfo.GetValue(n).ObjToString()
select new
{
l,
2022-06-07 15:43:04 +08:00
n
2022-05-16 13:15:52 +08:00
}).GroupBy(it => it.l).ToList();
2022-05-21 00:46:43 +08:00
foreach (var item in groupQuery)
2022-04-11 20:54:20 +08:00
{
2022-06-07 15:59:00 +08:00
var itemSelectList=item.Select(it => it.n);
if (sqlObj.Skip != null)
{
itemSelectList = itemSelectList
.Skip(sqlObj.Skip.Value);
}
if (sqlObj.Take != null)
{
itemSelectList = itemSelectList
.Take(sqlObj.Take.Value);
}
2022-04-29 23:30:03 +08:00
if (sqlObj.MappingExpressions.HasValue())
{
MappingFieldsHelper<T> helper = new MappingFieldsHelper<T>();
helper.NavEntity = navEntityInfo;
2022-05-05 09:13:59 +08:00
helper.Context = this.Context;
2022-04-29 23:30:03 +08:00
helper.RootEntity = this.Context.EntityMaintenance.GetEntityInfo<T>();
2022-06-07 15:59:00 +08:00
helper.SetChildList(navObjectNameColumnInfo, item.Key, itemSelectList.ToList(), sqlObj.MappingExpressions);
2022-04-29 23:30:03 +08:00
}
else
2022-04-18 12:04:35 +08:00
{
2022-04-29 23:30:03 +08:00
var instance = Activator.CreateInstance(navObjectNamePropety.PropertyType, true);
var ilist = instance as IList;
2022-06-07 15:59:00 +08:00
foreach (var value in itemSelectList.ToList())
2022-04-29 23:30:03 +08:00
{
ilist.Add(value);
}
2022-05-13 16:31:21 +08:00
navObjectNamePropety.SetValue(item.Key, instance);
2022-04-18 12:04:35 +08:00
}
2022-04-11 20:54:20 +08:00
}
2022-05-13 17:09:15 +08:00
foreach (var item in list)
{
2022-05-16 13:15:52 +08:00
if (navObjectNamePropety.GetValue(item) == null)
2022-05-13 17:09:15 +08:00
{
var instance = Activator.CreateInstance(navObjectNamePropety.PropertyType, true);
navObjectNamePropety.SetValue(item, instance);
}
}
2022-04-11 20:54:20 +08:00
}
2022-05-16 13:15:52 +08:00
else
{
//No navigation data set new List()
foreach (var item in list)
{
var instance = Activator.CreateInstance(navObjectNamePropety.PropertyType, true);
navObjectNamePropety.SetValue(item, instance);
}
}
2022-04-11 21:19:51 +08:00
}
2022-04-11 20:54:20 +08:00
}
2022-04-13 20:50:17 +08:00
2022-05-21 01:01:31 +08:00
private void Dynamic(List<object> list, Func<ISugarQueryable<object>, List<object>> selector, EntityInfo listItemEntity, System.Reflection.PropertyInfo navObjectNamePropety, EntityColumnInfo navObjectNameColumnInfo,Expression expression)
2022-04-29 18:50:48 +08:00
{
2022-05-06 12:36:27 +08:00
var args = navObjectNameColumnInfo.PropertyInfo.PropertyType.GetGenericArguments();
if (args.Length == 0)
{
2022-05-21 01:01:31 +08:00
DynamicOneToOne(list,selector,listItemEntity, navObjectNamePropety, navObjectNameColumnInfo,expression);
2022-05-06 12:36:27 +08:00
return;
}
var navEntity = args[0];
2022-06-08 19:22:25 +08:00
this.Context.InitMappingInfo(navEntity);
2022-04-29 18:50:48 +08:00
var navEntityInfo = this.Context.EntityMaintenance.GetEntityInfo(navEntity);
var sqlObj = GetWhereSql(navObjectNameColumnInfo.Navigat.Name);
2022-05-21 01:01:31 +08:00
Check.ExceptionEasy(sqlObj.MappingExpressions.IsNullOrEmpty(), $"{expression} error,dynamic need MappingField ,Demo: Includes(it => it.Books.MappingField(z=>z.studenId,()=>it.StudentId).ToList())", $"{expression} 解析出错,自定义映射需要 MappingField ,例子: Includes(it => it.Books.MappingField(z=>z.studenId,()=>it.StudentId).ToList())");
2022-04-29 18:50:48 +08:00
if (list.Any() && navObjectNamePropety.GetValue(list.First()) == null)
{
MappingFieldsHelper<T> helper = new MappingFieldsHelper<T>();
helper.Context = this.Context;
helper.NavEntity = navEntityInfo;
helper.RootEntity = this.Context.EntityMaintenance.GetEntityInfo<T>();
2022-05-05 09:13:59 +08:00
var whereSql = helper.GetMppingSql(list, sqlObj.MappingExpressions);
2022-04-29 18:50:48 +08:00
var navList = selector(this.Context.Queryable<object>().AS(navEntityInfo.DbTableName).AddParameters(sqlObj.Parameters).Where(whereSql,true).WhereIF(sqlObj.WhereString.HasValue(), sqlObj.WhereString).Select(sqlObj.SelectString).OrderByIF(sqlObj.OrderByString.HasValue(), sqlObj.OrderByString));
if (navList.HasValue())
{
foreach (var item in list)
{
helper.SetChildList(navObjectNameColumnInfo, item, navList, sqlObj.MappingExpressions);
}
}
}
}
2022-05-06 12:36:27 +08:00
2022-05-21 01:01:31 +08:00
private void DynamicOneToOne(List<object> list, Func<ISugarQueryable<object>, List<object>> selector, EntityInfo listItemEntity, System.Reflection.PropertyInfo navObjectNamePropety, EntityColumnInfo navObjectNameColumnInfo,Expression expression)
2022-05-06 12:36:27 +08:00
{
var navEntity = navObjectNameColumnInfo.PropertyInfo.PropertyType;
var navEntityInfo = this.Context.EntityMaintenance.GetEntityInfo(navEntity);
2022-06-08 20:54:19 +08:00
this.Context.InitMappingInfo(navEntity);
2022-05-06 12:36:27 +08:00
var sqlObj = GetWhereSql(navObjectNameColumnInfo.Navigat.Name);
2022-05-21 01:01:31 +08:00
Check.ExceptionEasy(sqlObj.MappingExpressions.IsNullOrEmpty(), $"{expression} errordynamic need MappingField ,Demo: Includes(it => it.Books.MappingField(z=>z.studenId,()=>it.StudentId).ToList())", $"{expression}解析出错, 自定义映射需要 MappingField ,例子: Includes(it => it.Books.MappingField(z=>z.studenId,()=>it.StudentId).ToList())");
2022-05-06 12:36:27 +08:00
if (list.Any() && navObjectNamePropety.GetValue(list.First()) == null)
{
MappingFieldsHelper<T> helper = new MappingFieldsHelper<T>();
helper.Context = this.Context;
helper.NavEntity = navEntityInfo;
helper.RootEntity = this.Context.EntityMaintenance.GetEntityInfo<T>();
var whereSql = helper.GetMppingSql(list, sqlObj.MappingExpressions);
var navList = selector(this.Context.Queryable<object>().AS(navEntityInfo.DbTableName).AddParameters(sqlObj.Parameters).Where(whereSql, true).WhereIF(sqlObj.WhereString.HasValue(), sqlObj.WhereString).Select(sqlObj.SelectString).OrderByIF(sqlObj.OrderByString.HasValue(), sqlObj.OrderByString));
if (navList.HasValue())
{
foreach (var item in list)
{
helper.SetChildItem(navObjectNameColumnInfo, item, navList, sqlObj.MappingExpressions);
}
}
}
}
2022-04-19 19:44:28 +08:00
private SqlInfo GetWhereSql(string properyName=null)
2022-04-13 20:50:17 +08:00
{
if (_ListCallFunc == null|| _ListCallFunc.Count==0) return new SqlInfo();
List<string> where = new List<string>();
List<string> oredrBy = new List<string>();
_ListCallFunc.Reverse();
SqlInfo result = new SqlInfo();
2022-04-13 21:10:02 +08:00
result.Parameters = new List<SugarParameter>();
2022-04-13 21:37:16 +08:00
var isList = false;
2022-09-19 20:48:01 +08:00
int parameterIndex = 0;
2022-04-13 20:50:17 +08:00
foreach (var item in _ListCallFunc)
{
var method = item as MethodCallExpression;
2022-04-13 21:10:02 +08:00
var queryable = this.Context.Queryable<object>();
2022-04-13 20:50:17 +08:00
if (method.Method.Name == "Where")
{
2022-07-30 18:38:03 +08:00
if (method.Arguments[1].Type == typeof(List<IConditionalModel>))
{
//var x=method.Arguments[1];
var conditionals = ExpressionTool.GetExpressionValue(method.Arguments[1]) as List<IConditionalModel>;
2022-09-18 15:02:47 +08:00
if (conditionals.Count > 0)
{
var whereObj = queryable.QueryBuilder.Builder.ConditionalModelToSql(conditionals);
where.Add(whereObj.Key);
if(whereObj.Value!=null)
result.Parameters.AddRange(whereObj.Value);
}
2022-07-30 18:38:03 +08:00
}
else
{
2022-09-19 20:48:01 +08:00
queryable.QueryBuilder.LambdaExpressions.ParameterIndex = parameterIndex;
2022-07-30 18:38:03 +08:00
CheckHasRootShortName(method.Arguments[0], method.Arguments[1]);
var exp = method.Arguments[1];
where.Add(" " + queryable.QueryBuilder.GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString());
SetTableShortName(result, queryable);
2022-09-19 20:48:01 +08:00
parameterIndex=queryable.QueryBuilder.LambdaExpressions.ParameterIndex ;
2022-07-30 18:38:03 +08:00
}
2022-04-13 20:50:17 +08:00
}
2022-04-15 10:44:41 +08:00
else if (method.Method.Name == "WhereIF")
2022-04-14 19:22:48 +08:00
{
var isOk = LambdaExpression.Lambda(method.Arguments[1]).Compile().DynamicInvoke();
if (isOk.ObjToBool())
{
2022-09-19 20:48:01 +08:00
queryable.QueryBuilder.LambdaExpressions.ParameterIndex = parameterIndex;
2022-04-14 19:22:48 +08:00
var exp = method.Arguments[2];
2022-04-30 00:34:27 +08:00
CheckHasRootShortName(method.Arguments[1], method.Arguments[2]);
2022-04-14 19:22:48 +08:00
where.Add(" " + queryable.QueryBuilder.GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString());
2022-07-23 14:12:03 +08:00
SetTableShortName(result, queryable);
2022-09-19 20:48:01 +08:00
parameterIndex = queryable.QueryBuilder.LambdaExpressions.ParameterIndex;
2022-04-14 19:22:48 +08:00
}
}
2022-04-13 20:50:17 +08:00
else if (method.Method.Name == "OrderBy")
{
var exp = method.Arguments[1];
2022-04-14 19:22:48 +08:00
oredrBy.Add(" " + queryable.QueryBuilder.GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString());
2022-07-23 14:12:03 +08:00
SetTableShortName(result, queryable);
2022-04-13 20:50:17 +08:00
}
2022-04-29 18:50:48 +08:00
else if (method.Method.Name == "MappingField")
{
if (result.MappingExpressions == null)
result.MappingExpressions = new List<MappingFieldsExpression>();
result.MappingExpressions.Add(new MappingFieldsExpression()
{
LeftColumnExpression = method.Arguments[1],
RightColumnExpression = method.Arguments[2]
});
}
2022-04-18 15:17:11 +08:00
else if (method.Method.Name == "Select")
{
var exp = method.Arguments[1];
2022-04-19 13:47:33 +08:00
var newExp = (exp as LambdaExpression).Body;
2022-04-18 15:17:11 +08:00
var types = exp.Type.GetGenericArguments();
if (types != null && types.Length > 0)
{
var type = types[0];
var entityInfo = this.Context.EntityMaintenance.GetEntityInfo(type);
2022-04-19 14:03:14 +08:00
this.Context.InitMappingInfo(type);
2022-07-30 18:38:03 +08:00
Check.ExceptionEasy(newExp.Type != entityInfo.Type, $" new {newExp.Type.Name}is error ,use Select(it=>new {entityInfo.Type.Name})", $"new {newExp.Type.Name}是错误的请使用Select(it=>new {entityInfo.Type.Name})");
2022-04-18 15:17:11 +08:00
if (entityInfo.Columns.Count(x => x.Navigat != null) == 0)
{
result.SelectString = (" " + queryable.QueryBuilder.GetExpressionValue(exp, ResolveExpressType.SelectSingle).GetString());
}
else
{
var pkInfo = entityInfo.Columns.FirstOrDefault(x => x.IsPrimarykey);
if (pkInfo != null)
{
var pkName = pkInfo.DbColumnName;
AppColumns(result, queryable, pkName);
}
2022-07-30 18:38:03 +08:00
foreach (var nav in entityInfo.Columns.Where(x => x.Navigat != null && x.Navigat.NavigatType == NavigateType.OneToOne))
2022-04-18 15:17:11 +08:00
{
var navColumn = entityInfo.Columns.FirstOrDefault(it => it.PropertyName == nav.Navigat.Name);
2022-04-29 18:50:48 +08:00
if (navColumn != null)
2022-04-18 15:17:11 +08:00
{
AppColumns(result, queryable, navColumn.DbColumnName);
}
}
}
2022-04-19 19:44:28 +08:00
if (properyName != null)
{
var fkColumnsInfo = entityInfo.Columns.FirstOrDefault(x => x.PropertyName == properyName);
if (fkColumnsInfo != null)
{
var fkName = fkColumnsInfo.DbColumnName;
AppColumns(result, queryable, fkName);
}
}
2022-04-18 15:17:11 +08:00
}
}
2022-04-13 20:50:17 +08:00
else if (method.Method.Name == "OrderByDescending")
{
var exp = method.Arguments[1];
2022-04-14 19:22:48 +08:00
oredrBy.Add(" " + queryable.QueryBuilder.GetExpressionValue(exp, ResolveExpressType.WhereSingle).GetString() + " DESC");
2022-04-13 20:50:17 +08:00
}
2022-06-07 15:43:04 +08:00
else if (method.Method.Name == "Skip")
{
var exp = method.Arguments[1];
2022-06-07 16:50:35 +08:00
if (exp is BinaryExpression)
{
result.Skip = (int)ExpressionTool.DynamicInvoke(exp);
}
else
{
result.Skip = (int)ExpressionTool.GetExpressionValue(exp);
}
2022-06-07 15:43:04 +08:00
}
else if (method.Method.Name == "Take")
{
var exp = method.Arguments[1];
2022-06-07 16:50:35 +08:00
if (exp is BinaryExpression)
{
result.Take = (int)ExpressionTool.DynamicInvoke(exp);
}
else
{
result.Take = (int)ExpressionTool.GetExpressionValue(exp);
}
2022-06-07 15:43:04 +08:00
}
2022-04-13 20:50:17 +08:00
else if (method.Method.Name == "ToList")
2022-04-13 21:37:16 +08:00
{
isList = true;
2022-04-13 20:50:17 +08:00
}
2022-04-14 19:22:48 +08:00
else
2022-04-13 20:50:17 +08:00
{
Check.ExceptionEasy($"no support {item}", $"不支持表达式{item} 不支持方法{method.Method.Name}");
}
2022-04-13 21:10:02 +08:00
if(queryable.QueryBuilder.Parameters!=null)
result.Parameters.AddRange(queryable.QueryBuilder.Parameters);
2022-04-13 20:50:17 +08:00
}
if (where.Any())
{
2022-04-30 00:34:27 +08:00
Check.ExceptionEasy(isList == false, $"{_ListCallFunc.First()} need is ToList()", $"{_ListCallFunc.First()} 需要ToList");
2022-04-13 20:50:17 +08:00
result.WhereString= String.Join(" AND ", where);
}
if (oredrBy.Any())
{
2022-04-30 00:34:27 +08:00
Check.ExceptionEasy(isList == false, $"{_ListCallFunc.First()} need is ToList()", $"{_ListCallFunc.First()} 需要ToList");
2022-04-13 20:50:17 +08:00
result.OrderByString = String.Join(" , ", oredrBy);
}
2022-04-19 13:47:33 +08:00
if (result.SelectString.HasValue())
{
2022-04-30 00:34:27 +08:00
Check.ExceptionEasy(isList == false, $"{_ListCallFunc.First()} need is ToList()", $"{_ListCallFunc.First()} 需要ToList");
2022-04-19 13:47:33 +08:00
result.OrderByString = String.Join(" , ", oredrBy);
}
2022-04-13 20:50:17 +08:00
return result;
}
2022-07-23 14:12:03 +08:00
private static void SetTableShortName(SqlInfo result, ISugarQueryable<object> queryable)
{
if (queryable.QueryBuilder.TableShortName.HasValue()&& result.TableShortName.IsNullOrEmpty())
{
result.TableShortName = queryable.QueryBuilder.TableShortName;
}
}
2022-04-18 15:17:11 +08:00
private static void AppColumns(SqlInfo result, ISugarQueryable<object> queryable, string columnName)
{
var selectPkName = queryable.SqlBuilder.GetTranslationColumnName(columnName);
if (result.SelectString.HasValue() && !result.SelectString.ToLower().Contains(selectPkName.ToLower()))
{
result.SelectString = result.SelectString + "," + selectPkName;
}
}
2022-07-13 16:59:25 +08:00
public void CheckHasRootShortName(Expression rootExpression, Expression childExpression)
2022-04-30 00:34:27 +08:00
{
var rootShortName = GetShortName(rootExpression);
2022-05-19 16:05:58 +08:00
if (rootShortName.HasValue()&& childExpression.ToString().Contains($" {rootShortName}."))
2022-04-30 00:34:27 +08:00
{
Check.ExceptionEasy($".Where({childExpression}) no support {rootShortName}.Field, Use .MappingField",$".Where({childExpression})禁止出{rootShortName}.字段 , 你可以使用.MappingField(z=>z.字段,()=>{rootShortName}.字段) 与主表字段进行过滤");
}
2022-05-21 00:46:43 +08:00
else if (rootShortName.HasValue() && childExpression.ToString().Contains($"({rootShortName}."))
{
Check.ExceptionEasy($".Where({childExpression}) no support {rootShortName}.Field, Use .MappingField", $".Where({childExpression})禁止出{rootShortName}.字段 , 你可以使用.MappingField(z=>z.字段,()=>{rootShortName}.字段) 与主表字段进行过滤");
}
2022-04-30 00:34:27 +08:00
}
private static string GetShortName(Expression expression1)
{
string shortName = null;
if (expression1 is MemberExpression)
{
var shortNameExpression = (expression1 as MemberExpression).Expression;
if (shortNameExpression != null && shortNameExpression.Type == typeof(T))
{
if (shortNameExpression is ParameterExpression)
{
shortName = (shortNameExpression as ParameterExpression).Name;
}
}
}
return shortName;
}
2022-04-18 15:17:11 +08:00
2022-04-13 20:50:17 +08:00
public class SqlInfo
{
2022-06-07 15:43:04 +08:00
public int? Take { get; set; }
public int? Skip { get; set; }
2022-04-13 20:50:17 +08:00
public string WhereString { get; set; }
public string OrderByString { get; set; }
2022-04-18 15:17:11 +08:00
public string SelectString { get; set; }
2022-04-13 21:10:02 +08:00
public List<SugarParameter> Parameters { get; set; }
2022-04-29 18:50:48 +08:00
public List<MappingFieldsExpression> MappingExpressions { get; set; }
2022-07-23 14:12:03 +08:00
public string TableShortName { get; set; }
2022-04-13 20:50:17 +08:00
}
2022-04-11 14:04:22 +08:00
}
}