调整查询条件类名

This commit is contained in:
wintel
2024-06-12 21:22:16 +08:00
parent 71a8a8e25d
commit 35ff148b68
9 changed files with 103 additions and 64 deletions

View File

@@ -175,7 +175,7 @@ namespace Infrastructure
{ {
if (!string.IsNullOrEmpty(filterjson)) if (!string.IsNullOrEmpty(filterjson))
{ {
var filterGroup = JsonHelper.Instance.Deserialize<FilterGroup>(filterjson); var filterGroup = JsonHelper.Instance.Deserialize<QueryObject>(filterjson);
query = GenerateFilter(query, parametername, filterGroup); query = GenerateFilter(query, parametername, filterGroup);
} }
@@ -186,7 +186,7 @@ namespace Infrastructure
{ {
if (!string.IsNullOrEmpty(filterjson)) if (!string.IsNullOrEmpty(filterjson))
{ {
var filterGroup = JsonHelper.Instance.Deserialize<FilterGroup>(filterjson); var filterGroup = JsonHelper.Instance.Deserialize<QueryObject>(filterjson);
query = GenerateFilter(query, parametername, filterGroup); query = GenerateFilter(query, parametername, filterGroup);
} }
@@ -199,13 +199,13 @@ namespace Infrastructure
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <param name="query"></param> /// <param name="query"></param>
/// <param name="parametername"></param> /// <param name="parametername"></param>
/// <param name="filterGroup"></param> /// <param name="queryObject"></param>
/// <returns></returns> /// <returns></returns>
public static IQueryable<T> GenerateFilter<T>(this IQueryable<T> query, string parametername, public static IQueryable<T> GenerateFilter<T>(this IQueryable<T> query, string parametername,
FilterGroup filterGroup) QueryObject queryObject)
{ {
var param = CreateLambdaParam<T>(parametername); var param = CreateLambdaParam<T>(parametername);
Expression result = ConvertGroup<T>(filterGroup, param); Expression result = ConvertGroup<T>(queryObject, param);
query = query.Where(param.GenerateTypeLambda<T>(result)); query = query.Where(param.GenerateTypeLambda<T>(result));
return query; return query;
} }
@@ -215,14 +215,14 @@ namespace Infrastructure
/// </summary> /// </summary>
/// <param name="query"></param> /// <param name="query"></param>
/// <param name="parametername"></param> /// <param name="parametername"></param>
/// <param name="filterGroup"></param> /// <param name="queryObject"></param>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
public static ISugarQueryable<T> GenerateFilter<T>(this ISugarQueryable<T> query, string parametername, public static ISugarQueryable<T> GenerateFilter<T>(this ISugarQueryable<T> query, string parametername,
FilterGroup filterGroup) QueryObject queryObject)
{ {
var param = CreateLambdaParam<T>(parametername); var param = CreateLambdaParam<T>(parametername);
Expression result = ConvertGroup<T>(filterGroup, param); Expression result = ConvertGroup<T>(queryObject, param);
query = query.Where(param.GenerateTypeLambda<T>(result)); query = query.Where(param.GenerateTypeLambda<T>(result));
return query; return query;
} }
@@ -230,25 +230,25 @@ namespace Infrastructure
/// <summary> /// <summary>
/// 转换filtergroup为表达式 /// 转换filtergroup为表达式
/// </summary> /// </summary>
/// <param name="filterGroup"></param> /// <param name="queryObject"></param>
/// <param name="param"></param> /// <param name="param"></param>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
public static Expression ConvertGroup<T>(FilterGroup filterGroup, ParameterExpression param) public static Expression ConvertGroup<T>(QueryObject queryObject, ParameterExpression param)
{ {
if (filterGroup == null) return null; if (queryObject == null) return null;
if (filterGroup.Filters.Length == 1 &&(filterGroup.Children == null || !filterGroup.Children.Any())) //只有一个条件 if (queryObject.Filters.Length == 1 &&(queryObject.Children == null || !queryObject.Children.Any())) //只有一个条件
{ {
return param.GenerateBody<T>(filterGroup.Filters[0]); return param.GenerateBody<T>(queryObject.Filters[0]);
} }
Expression result = ConvertFilters<T>(filterGroup.Filters, param, filterGroup.Operation); Expression result = ConvertFilters<T>(queryObject.Filters, param, queryObject.Operation);
Expression gresult = ConvertGroup<T>(filterGroup.Children, param, filterGroup.Operation); Expression gresult = ConvertGroup<T>(queryObject.Children, param, queryObject.Operation);
if (gresult == null) return result; if (gresult == null) return result;
if (result == null) return gresult; if (result == null) return gresult;
if (filterGroup.Operation == "and") if (queryObject.Operation == "and")
{ {
return result.AndAlso(gresult); return result.AndAlso(gresult);
} }
@@ -266,7 +266,7 @@ namespace Infrastructure
/// <param name="operation"></param> /// <param name="operation"></param>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
private static Expression ConvertGroup<T>(FilterGroup[] groups, ParameterExpression param, string operation) private static Expression ConvertGroup<T>(QueryObject[] groups, ParameterExpression param, string operation)
{ {
if (groups == null || !groups.Any()) return null; if (groups == null || !groups.Any()) return null;

View File

@@ -1,25 +1,64 @@
namespace Infrastructure namespace Infrastructure
{ {
public class Filter /// <summary>
{ /// 查询表达式中的最小单元,如:
public string Key { get; set; } /// new Filter {Key = "name", Value = "yubaolee", Contrast = "=="},
public string Value { get; set; } /// new Filter {Key = "name", Value = "yubaolee", Contrast = "contains"},
public string Contrast { get; set; } /// new Filter {Key = "age", Value = "10,20,30", Contrast = "in"},
/// new Filter {Key = "10,20,30", Value = "40", Contrast = "intersect"}
public string Text { get; set; } /// </summary>
} public class Filter
{
public class FilterGroup /// <summary>
{ /// 过滤条件的关键字。
/// <summary> /// </summary>
/// or /and public string Key { get; set; }
/// </summary>
public string Operation { get; set; } /// <summary>
public Filter[] Filters { get; set; } /// 通常为值yubaolee、10、10,20,30等。
public FilterGroup[] Children { get; set; } /// </summary>
} public string Value { get; set; }
/// <summary>
/// 通常为运算符,如:==、contains、in、intersect等。
/// </summary>
public string Contrast { get; set; }
/// <summary>
/// 对于特殊值的说明
/// </summary>
public string Text { get; set; }
}
/// <summary>
/// 查询对象类,用于封装查询条件。
/// </summary>
public class QueryObject
{
/// <summary>
/// 操作类型定义了查询条件之间的逻辑关系如OR、AND。
/// </summary>
/// <remarks>
/// 该属性决定了如何组合多个过滤条件,以构建复杂的查询逻辑。
/// </remarks>
public string Operation { get; set; }
/// <summary>
/// 过滤器数组,包含一组过滤条件。
/// </summary>
public Filter[] Filters { get; set; }
/// <summary>
/// 子查询对象数组,支持嵌套查询。
/// </summary>
/// <remarks>
/// 通过嵌套查询对象,可以构建复杂的查询逻辑,处理更复杂的数据关系。
/// </remarks>
public QueryObject[] Children { get; set; }
}
} }

View File

@@ -11,7 +11,7 @@ public static class QueryObjExtension
/// <summary> /// <summary>
/// 根据过滤器组构建查询。 /// 根据过滤器组构建查询。
/// </summary> /// </summary>
public static string BuildQuery(this FilterGroup query) public static string BuildQuery(this QueryObject query)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
BuildQuery(query, sb); BuildQuery(query, sb);
@@ -21,7 +21,7 @@ public static class QueryObjExtension
/// <summary> /// <summary>
/// 递归构建查询字符串。 /// 递归构建查询字符串。
/// </summary> /// </summary>
private static void BuildQuery(FilterGroup query, StringBuilder sb) private static void BuildQuery(QueryObject query, StringBuilder sb)
{ {
// 构建当前过滤器组的过滤条件 // 构建当前过滤器组的过滤条件
if (query.Filters != null && query.Filters.Length > 0) if (query.Filters != null && query.Filters.Length > 0)

View File

@@ -9,7 +9,7 @@ namespace Infrastructure.Test
[Test] [Test]
public void Convert() public void Convert()
{ {
FilterGroup sub = new FilterGroup QueryObject sub = new QueryObject
{ {
Operation = "or" Operation = "or"
}; };
@@ -19,22 +19,22 @@ namespace Infrastructure.Test
new Filter {Key = "c3", Value = "10,20,30", Contrast = "in"} new Filter {Key = "c3", Value = "10,20,30", Contrast = "in"}
}; };
FilterGroup filterGroup = new FilterGroup QueryObject queryObject = new QueryObject
{ {
Operation = "and" Operation = "and"
}; };
filterGroup.Filters = new[] queryObject.Filters = new[]
{ {
new Filter {Key = "c1", Value = "name", Contrast = "contains"}, new Filter {Key = "c1", Value = "name", Contrast = "contains"},
new Filter {Key = "10,20,30", Value = "40", Contrast = "intersect"} new Filter {Key = "10,20,30", Value = "40", Contrast = "intersect"}
}; };
filterGroup.Children = new[] queryObject.Children = new[]
{ {
sub sub
}; };
var expression = DynamicLinq.ConvertGroup<TestOjb>(filterGroup, var expression = DynamicLinq.ConvertGroup<TestOjb>(queryObject,
Expression.Parameter(typeof(TestOjb), "c")); Expression.Parameter(typeof(TestOjb), "c"));
Console.WriteLine(expression.ToString()); Console.WriteLine(expression.ToString());

View File

@@ -63,7 +63,7 @@ namespace OpenAuth.App
string.Join(',',orgs)); string.Join(',',orgs));
} }
return UnitWork.Find<T>(null).GenerateFilter(parametername, return UnitWork.Find<T>(null).GenerateFilter(parametername,
JsonHelper.Instance.Deserialize<FilterGroup>(rule.PrivilegeRules)); JsonHelper.Instance.Deserialize<QueryObject>(rule.PrivilegeRules));
} }
/// <summary> /// <summary>

View File

@@ -75,7 +75,7 @@ namespace OpenAuth.App
string.Join(',',orgs)); string.Join(',',orgs));
} }
return SugarClient.Queryable<T>().GenerateFilter(parametername, return SugarClient.Queryable<T>().GenerateFilter(parametername,
JsonHelper.Instance.Deserialize<FilterGroup>(rule.PrivilegeRules)); JsonHelper.Instance.Deserialize<QueryObject>(rule.PrivilegeRules));
} }
/// <summary> /// <summary>

View File

@@ -18,7 +18,7 @@ namespace OpenAuth.App.Test
var services = new ServiceCollection(); var services = new ServiceCollection();
var cachemock = new Mock<ICacheContext>(); var cachemock = new Mock<ICacheContext>();
cachemock.Setup(x => x.Get<UserAuthSession>("tokentest")).Returns(new UserAuthSession { Account = "Systems" }); cachemock.Setup(x => x.Get<UserAuthSession>("tokentest")).Returns(new UserAuthSession { Account = "admin" });
services.AddScoped(x => cachemock.Object); services.AddScoped(x => cachemock.Object);
var httpContextAccessorMock = new Mock<IHttpContextAccessor>(); var httpContextAccessorMock = new Mock<IHttpContextAccessor>();
@@ -37,7 +37,7 @@ namespace OpenAuth.App.Test
{ {
var app = _autofacServiceProvider.GetService<ResourceApp>(); var app = _autofacServiceProvider.GetService<ResourceApp>();
var result = app.Load(new QueryResourcesReq()); var result = app.Load(new QueryResourcesReq());
Console.WriteLine(JsonHelper.Instance.Serialize(result)); Console.WriteLine(JsonHelper.Instance.Serialize(result.Result));
} }
[Test] [Test]
@@ -46,7 +46,7 @@ namespace OpenAuth.App.Test
var auth = _autofacServiceProvider.GetService<IAuth>(); var auth = _autofacServiceProvider.GetService<IAuth>();
var app = _autofacServiceProvider.GetService<DataPrivilegeRuleApp>(); var app = _autofacServiceProvider.GetService<DataPrivilegeRuleApp>();
//该测试解析为:针对资源列表,【管理员】可以看到所有,角色为【神】或【测试】的只能看到自己创建的 //该测试解析为:针对资源列表,【管理员】可以看到所有,角色为【神】或【测试】的只能看到自己创建的
var filterGroup = new FilterGroup var filterGroup = new QueryObject
{ {
Operation = "or" Operation = "or"
}; };
@@ -61,7 +61,7 @@ namespace OpenAuth.App.Test
}; };
filterGroup.Children = new[] filterGroup.Children = new[]
{ {
new FilterGroup //登录用户角色包含【测试】或包含【神】的,只能看到自己的 new QueryObject //登录用户角色包含【测试】或包含【神】的,只能看到自己的
{ {
Operation = "and", Operation = "and",
Filters = new Filter[] Filters = new Filter[]

View File

@@ -59,7 +59,7 @@ namespace OpenAuth.Repository.Test
[Test] [Test]
public void TestDynamic() public void TestDynamic()
{ {
FilterGroup sub = new FilterGroup QueryObject sub = new QueryObject
{ {
Operation = "or" Operation = "or"
}; };
@@ -69,24 +69,24 @@ namespace OpenAuth.Repository.Test
new Filter {Key = "Sex", Value = "10", Contrast = "=="} new Filter {Key = "Sex", Value = "10", Contrast = "=="}
}; };
FilterGroup filterGroup = new FilterGroup QueryObject queryObject = new QueryObject
{ {
Operation = "and" Operation = "and"
}; };
filterGroup.Filters = new[] queryObject.Filters = new[]
{ {
new Filter {Key = "Account", Value = "name", Contrast = "=="}, new Filter {Key = "Account", Value = "name", Contrast = "=="},
new Filter {Key = "Password", Value = "10", Contrast = "=="} new Filter {Key = "Password", Value = "10", Contrast = "=="}
}; };
filterGroup.Children = new[] queryObject.Children = new[]
{ {
sub sub
}; };
var dbcontext = _autofacServiceProvider.GetService<OpenAuthDBContext>(); var dbcontext = _autofacServiceProvider.GetService<OpenAuthDBContext>();
var query = dbcontext.Users.GenerateFilter("c",JsonHelper.Instance.Serialize(filterGroup)); var query = dbcontext.Users.GenerateFilter("c",JsonHelper.Instance.Serialize(queryObject));
Console.WriteLine(query.Expression.ToString()); Console.WriteLine(query.Expression.ToString());
} }
} }

View File

@@ -73,7 +73,7 @@ namespace OpenAuth.Repository.Test
[Test] [Test]
public void TestDynamic() public void TestDynamic()
{ {
FilterGroup sub = new FilterGroup QueryObject sub = new QueryObject
{ {
Operation = "or" Operation = "or"
}; };
@@ -83,24 +83,24 @@ namespace OpenAuth.Repository.Test
new Filter {Key = "Sex", Value = "10", Contrast = "=="} new Filter {Key = "Sex", Value = "10", Contrast = "=="}
}; };
FilterGroup filterGroup = new FilterGroup QueryObject queryObject = new QueryObject
{ {
Operation = "and" Operation = "and"
}; };
filterGroup.Filters = new[] queryObject.Filters = new[]
{ {
new Filter {Key = "Account", Value = "name", Contrast = "=="}, new Filter {Key = "Account", Value = "name", Contrast = "=="},
new Filter {Key = "Password", Value = "10", Contrast = "=="} new Filter {Key = "Password", Value = "10", Contrast = "=="}
}; };
filterGroup.Children = new[] queryObject.Children = new[]
{ {
sub sub
}; };
var sugarClient = _autofacServiceProvider.GetService<ISqlSugarClient>(); var sugarClient = _autofacServiceProvider.GetService<ISqlSugarClient>();
var query = sugarClient.Queryable<User>().GenerateFilter("c",filterGroup); var query = sugarClient.Queryable<User>().GenerateFilter("c",queryObject);
Console.WriteLine(query.ToSqlString()); Console.WriteLine(query.ToSqlString());
} }
} }