Merge pull request #1123 from sampsonye/feature-toparentlist-support-where

防范风险,Copy原代码后修改重载
This commit is contained in:
果糖网
2023-01-13 17:10:26 +08:00
committed by GitHub
9 changed files with 471 additions and 19 deletions

View File

@@ -245,7 +245,49 @@ namespace SqlSugar
return GetChildList(parentIdExpression, pk, list, primaryKeyValue, isContainOneself);
}
public List<T> ToParentList(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression = default)
public List<T> ToParentList(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue)
{
var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
var isTreeKey = entity.Columns.Any(it => it.IsTreeKey);
if (isTreeKey)
{
return _ToParentListByTreeKey(parentIdExpression, primaryKeyValue);
}
List<T> result = new List<T>() { };
Check.Exception(entity.Columns.Where(it => it.IsPrimarykey).Count() == 0, "No Primary key");
var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name;
var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName);
var parentPropertyName = ParentInfo.DbColumnName;
var tableName = this.QueryBuilder.GetTableNameString;
if (this.QueryBuilder.IsSingle() == false)
{
if (this.QueryBuilder.JoinQueryInfos.Count > 0)
{
tableName = this.QueryBuilder.JoinQueryInfos.First().TableName;
}
if (this.QueryBuilder.EasyJoinInfos.Count > 0)
{
tableName = this.QueryBuilder.JoinQueryInfos.First().TableName;
}
}
var current = this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingle(primaryKeyValue);
if (current != null)
{
result.Add(current);
object parentId = ParentInfo.PropertyInfo.GetValue(current, null);
int i = 0;
while (parentId != null && this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).In(parentId).Any())
{
Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限100检查最顶层的ParentId是否是null或者0"));
var parent = this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingle(parentId);
result.Add(parent);
parentId = ParentInfo.PropertyInfo.GetValue(parent, null);
++i;
}
}
return result;
}
public List<T> ToParentList(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression)
{
var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
var isTreeKey = entity.Columns.Any(it => it.IsTreeKey);

View File

@@ -504,8 +504,49 @@ ParameterT parameter)
var list = await this.ToListAsync();
return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue);
}
public async Task<List<T>> ToParentListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression = default)
public async Task<List<T>> ToParentListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue)
{
List<T> result = new List<T>() { };
var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
var isTreeKey = entity.Columns.Any(it => it.IsTreeKey);
if (isTreeKey)
{
return await _ToParentListByTreeKeyAsync(parentIdExpression, primaryKeyValue);
}
Check.Exception(entity.Columns.Where(it => it.IsPrimarykey).Count() == 0, "No Primary key");
var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name;
var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName);
var parentPropertyName = ParentInfo.DbColumnName;
var tableName = this.QueryBuilder.GetTableNameString;
if (this.QueryBuilder.IsSingle() == false)
{
if (this.QueryBuilder.JoinQueryInfos.Count > 0)
{
tableName = this.QueryBuilder.JoinQueryInfos.First().TableName;
}
if (this.QueryBuilder.EasyJoinInfos.Count > 0)
{
tableName = this.QueryBuilder.JoinQueryInfos.First().TableName;
}
}
var current = await this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingleAsync(primaryKeyValue);
if (current != null)
{
result.Add(current);
object parentId = ParentInfo.PropertyInfo.GetValue(current, null);
int i = 0;
while (parentId != null && await this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).In(parentId).AnyAsync())
{
Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限100检查最顶层的ParentId是否是null或者0"));
var parent = await this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingleAsync(parentId);
result.Add(parent);
parentId = ParentInfo.PropertyInfo.GetValue(parent, null);
++i;
}
}
return result;
}
public async Task<List<T>> ToParentListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression)
{
List<T> result = new List<T>() { };
var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();

View File

@@ -20,7 +20,7 @@ namespace SqlSugar
public partial class QueryableProvider<T> : QueryableAccessory, ISugarQueryable<T>
{
#region Tree
private List<T> _ToParentListByTreeKey(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression = default)
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);
@@ -40,7 +40,7 @@ namespace SqlSugar
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>() {
var current = this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List<IConditionalModel>() {
new ConditionalModel()
{
ConditionalType = ConditionalType.Equal,
@@ -53,7 +53,7 @@ namespace SqlSugar
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>() {
while (parentId != null && this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).Where(new List<IConditionalModel>() {
new ConditionalModel()
{
ConditionalType = ConditionalType.Equal,
@@ -63,7 +63,65 @@ namespace SqlSugar
} }).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>() {
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,
@@ -79,7 +137,66 @@ namespace SqlSugar
return result;
}
private async Task<List<T>> _ToParentListByTreeKeyAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression = default)
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);

View File

@@ -178,8 +178,12 @@ namespace SqlSugar
string ToSqlString();
List<T> ToChildList(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, bool isContainOneself = true);
Task<List<T>> ToChildListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, bool isContainOneself = true);
List<T> ToParentList(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression = default);
Task<List<T>> ToParentListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression = default);
List<T> ToParentList(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue);
List<T> ToParentList(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression);
Task<List<T>> ToParentListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue);
Task<List<T>> ToParentListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression);
List<T> ToTree(Expression<Func<T,IEnumerable<object>>> childListExpression, Expression<Func<T,object>> parentIdExpression,object rootValue);
Task<List<T>> ToTreeAsync(Expression<Func<T, IEnumerable<object>>> childListExpression, Expression<Func<T, object>> parentIdExpression, object rootValue);
List<T> ToTree(Expression<Func<T, IEnumerable<object>>> childListExpression, Expression<Func<T, object>> parentIdExpression, object rootValue, object[] childIds);

View File

@@ -13,12 +13,37 @@ namespace MySqlTest.Demo
{
public static void Init()
{
Task.Run(Test_ToParentList).Wait();
Test_ToParentList();
Test_ToParentListWhere();
Task.Run(Test_ToParentListAsync).Wait();
Task.Run(Test_ToParentListWhereAsync).Wait();
}
private static async Task Test_ToParentList()
private static void Test_ToParentList()
{
var db = GetInstance();
var data = db.Queryable<CustomerAddressTemplateDetail>().ToParentList(x => x.ParentCode, 2);
var data2 = db.Queryable<District>().ToParentList(x => x.ParentId, 110101004004);
}
private static void Test_ToParentListWhere()
{
var db = GetInstance();
var data = db.Queryable<CustomerAddressTemplateDetail>().ToParentList(x => x.ParentCode, 2, x => x.TemplateId == 1611933284013932544);
var data2 = db.Queryable<District>().ToParentList(x => x.ParentId, 110101004004,x=>x.DeletedAt==0);
}
private static async Task Test_ToParentListAsync()
{
var db = GetInstance();
var data = await db.Queryable<CustomerAddressTemplateDetail>().ToParentListAsync(x => x.ParentCode, 2);
var data2 = await db.Queryable<District>().ToParentListAsync(x => x.ParentId, 110101004004);
}
private static async Task Test_ToParentListWhereAsync()
{
var db = GetInstance();
var data = await db.Queryable<CustomerAddressTemplateDetail>().ToParentListAsync(x => x.ParentCode, 2, x => x.TemplateId == 1611933284013932544);
var data2 = await db.Queryable<District>().ToParentListAsync(x => x.ParentId, 110101004004, x => x.DeletedAt == 0);
}
private static SqlSugarClient GetInstance()
@@ -26,7 +51,7 @@ namespace MySqlTest.Demo
return new SqlSugarClient(new ConnectionConfig()
{
DbType = SqlSugar.DbType.MySql,
ConnectionString = Config.ConnectionString,
ConnectionString = "Data Source=192.168.95.11;port=33306;Database=cube;AllowLoadLocalInfile=true;User ID=root;Password=dljs2022;allowPublicKeyRetrieval=true;pooling=true;CharSet=utf8;sslmode=none;AllowUserVariables=true;",
InitKeyType = InitKeyType.Attribute,
IsAutoCloseConnection = true,
AopEvents = new AopEvents
@@ -70,6 +95,24 @@ namespace MySqlTest.Demo
}
[SugarTable("district", TableDescription = "省市区街道村5级信息(https://github.com/adyliu/china_area)")]
[SugarIndex("idx_parentid_level", nameof(ParentId), OrderByType.Asc, nameof(Level), OrderByType.Asc)]
public class District
{
[SugarColumn(IsPrimaryKey = true)]
public long Id { get; set; }
[SugarColumn(ColumnDescription = "上级Id")]
public long ParentId { get; set; }
[SugarColumn(ColumnDescription = "名称", Length = 128)]
public string Name { get; set; } = string.Empty;
[SugarColumn(ColumnDescription = "级别")]
public int Level { get; set; }
public long DeletedAt { get; set; }
}
}

View File

@@ -245,7 +245,49 @@ namespace SqlSugar
return GetChildList(parentIdExpression, pk, list, primaryKeyValue, isContainOneself);
}
public List<T> ToParentList(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression = default)
public List<T> ToParentList(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue)
{
var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
var isTreeKey = entity.Columns.Any(it => it.IsTreeKey);
if (isTreeKey)
{
return _ToParentListByTreeKey(parentIdExpression, primaryKeyValue);
}
List<T> result = new List<T>() { };
Check.Exception(entity.Columns.Where(it => it.IsPrimarykey).Count() == 0, "No Primary key");
var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name;
var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName);
var parentPropertyName = ParentInfo.DbColumnName;
var tableName = this.QueryBuilder.GetTableNameString;
if (this.QueryBuilder.IsSingle() == false)
{
if (this.QueryBuilder.JoinQueryInfos.Count > 0)
{
tableName = this.QueryBuilder.JoinQueryInfos.First().TableName;
}
if (this.QueryBuilder.EasyJoinInfos.Count > 0)
{
tableName = this.QueryBuilder.JoinQueryInfos.First().TableName;
}
}
var current = this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingle(primaryKeyValue);
if (current != null)
{
result.Add(current);
object parentId = ParentInfo.PropertyInfo.GetValue(current, null);
int i = 0;
while (parentId != null && this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).In(parentId).Any())
{
Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限100检查最顶层的ParentId是否是null或者0"));
var parent = this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingle(parentId);
result.Add(parent);
parentId = ParentInfo.PropertyInfo.GetValue(parent, null);
++i;
}
}
return result;
}
public List<T> ToParentList(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression)
{
var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
var isTreeKey = entity.Columns.Any(it => it.IsTreeKey);

View File

@@ -505,7 +505,49 @@ ParameterT parameter)
return GetTreeRoot(childListExpression, parentIdExpression, pk, list, rootValue);
}
public async Task<List<T>> ToParentListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression = default)
public async Task<List<T>> ToParentListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue)
{
List<T> result = new List<T>() { };
var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();
var isTreeKey = entity.Columns.Any(it => it.IsTreeKey);
if (isTreeKey)
{
return await _ToParentListByTreeKeyAsync(parentIdExpression, primaryKeyValue);
}
Check.Exception(entity.Columns.Where(it => it.IsPrimarykey).Count() == 0, "No Primary key");
var parentIdName = UtilConvert.ToMemberExpression((parentIdExpression as LambdaExpression).Body).Member.Name;
var ParentInfo = entity.Columns.First(it => it.PropertyName == parentIdName);
var parentPropertyName = ParentInfo.DbColumnName;
var tableName = this.QueryBuilder.GetTableNameString;
if (this.QueryBuilder.IsSingle() == false)
{
if (this.QueryBuilder.JoinQueryInfos.Count > 0)
{
tableName = this.QueryBuilder.JoinQueryInfos.First().TableName;
}
if (this.QueryBuilder.EasyJoinInfos.Count > 0)
{
tableName = this.QueryBuilder.JoinQueryInfos.First().TableName;
}
}
var current = await this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingleAsync(primaryKeyValue);
if (current != null)
{
result.Add(current);
object parentId = ParentInfo.PropertyInfo.GetValue(current, null);
int i = 0;
while (parentId != null && await this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).In(parentId).AnyAsync())
{
Check.Exception(i > 100, ErrorMessage.GetThrowMessage("Dead cycle", "出现死循环或超出循环上限100检查最顶层的ParentId是否是null或者0"));
var parent = await this.Context.Queryable<T>().AS(tableName).Filter(null, this.QueryBuilder.IsDisabledGobalFilter).InSingleAsync(parentId);
result.Add(parent);
parentId = ParentInfo.PropertyInfo.GetValue(parent, null);
++i;
}
}
return result;
}
public async Task<List<T>> ToParentListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression)
{
List<T> result = new List<T>() { };
var entity = this.Context.EntityMaintenance.GetEntityInfo<T>();

View File

@@ -20,7 +20,67 @@ namespace SqlSugar
public partial class QueryableProvider<T> : QueryableAccessory, ISugarQueryable<T>
{
#region Tree
private List<T> _ToParentListByTreeKey(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression = default)
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);
@@ -79,7 +139,66 @@ namespace SqlSugar
return result;
}
private async Task<List<T>> _ToParentListByTreeKeyAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression = default)
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);

View File

@@ -178,8 +178,10 @@ namespace SqlSugar
string ToSqlString();
List<T> ToChildList(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, bool isContainOneself = true);
Task<List<T>> ToChildListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, bool isContainOneself = true);
List<T> ToParentList(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression = default);
Task<List<T>> ToParentListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression = default);
List<T> ToParentList(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue);
List<T> ToParentList(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression);
Task<List<T>> ToParentListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue);
Task<List<T>> ToParentListAsync(Expression<Func<T, object>> parentIdExpression, object primaryKeyValue, Expression<Func<T, bool>> parentWhereExpression);
List<T> ToTree(Expression<Func<T,IEnumerable<object>>> childListExpression, Expression<Func<T,object>> parentIdExpression,object rootValue);
Task<List<T>> ToTreeAsync(Expression<Func<T, IEnumerable<object>>> childListExpression, Expression<Func<T, object>> parentIdExpression, object rootValue);
List<T> ToTree(Expression<Func<T, IEnumerable<object>>> childListExpression, Expression<Func<T, object>> parentIdExpression, object rootValue, object[] childIds);