mirror of
https://gitee.com/dotnetchina/OpenAuth.Net.git
synced 2025-04-05 17:38:01 +08:00
增加SqlSugar启动
This commit is contained in:
parent
0699413f39
commit
a6c79bea7c
@ -1,306 +1,324 @@
|
||||
// ***********************************************************************
|
||||
// Assembly : FairUtility
|
||||
// Author : Yubao Li
|
||||
// Created : 08-18-2015
|
||||
//
|
||||
// Last Modified By : Yubao Li
|
||||
// Last Modified On : 08-18-2015
|
||||
// ***********************************************************************
|
||||
// <copyright file="DynamicLinq.cs" company="">
|
||||
// Copyright (c) . All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>动态linq</summary>
|
||||
// ***********************************************************************
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Infrastructure
|
||||
{
|
||||
public static class DynamicLinq
|
||||
{
|
||||
public static ParameterExpression CreateLambdaParam<T>(string name)
|
||||
{
|
||||
return Expression.Parameter(typeof(T), name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建linq表达示的body部分
|
||||
/// </summary>
|
||||
public static Expression GenerateBody<T>(this ParameterExpression param, Filter filterObj)
|
||||
{
|
||||
PropertyInfo property = typeof(T).GetProperty(filterObj.Key);
|
||||
|
||||
Expression left = null; //组装左边
|
||||
//组装右边
|
||||
Expression right = null;
|
||||
|
||||
if (property != null)
|
||||
{
|
||||
left = Expression.Property(param, property);
|
||||
if (property.PropertyType == typeof(int))
|
||||
{
|
||||
right = Expression.Constant(int.Parse(filterObj.Value));
|
||||
}
|
||||
else if (property.PropertyType == typeof(DateTime))
|
||||
{
|
||||
right = Expression.Constant(DateTime.Parse(filterObj.Value));
|
||||
}
|
||||
else if (property.PropertyType == typeof(string))
|
||||
{
|
||||
right = Expression.Constant(filterObj.Value);
|
||||
}
|
||||
else if (property.PropertyType == typeof(decimal))
|
||||
{
|
||||
right = Expression.Constant(decimal.Parse(filterObj.Value));
|
||||
}
|
||||
else if (property.PropertyType == typeof(Guid))
|
||||
{
|
||||
right = Expression.Constant(Guid.Parse(filterObj.Value));
|
||||
}
|
||||
else if (property.PropertyType == typeof(bool))
|
||||
{
|
||||
right = Expression.Constant(filterObj.Value.Equals("1"));
|
||||
}
|
||||
else if (property.PropertyType == typeof(Guid?))
|
||||
{
|
||||
left = Expression.Property(left, "Value");
|
||||
right = Expression.Constant(Guid.Parse(filterObj.Value));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("暂不能解析该Key的类型");
|
||||
}
|
||||
}
|
||||
else //如果左边不是属性,直接是值的情况
|
||||
{
|
||||
left = Expression.Constant(filterObj.Key);
|
||||
right = Expression.Constant(filterObj.Value);
|
||||
}
|
||||
|
||||
//c.XXX=="XXX"
|
||||
Expression filter = Expression.Equal(left, right);
|
||||
switch (filterObj.Contrast)
|
||||
{
|
||||
case "<=":
|
||||
filter = Expression.LessThanOrEqual(left, right);
|
||||
break;
|
||||
|
||||
case "<":
|
||||
filter = Expression.LessThan(left, right);
|
||||
break;
|
||||
|
||||
case ">":
|
||||
filter = Expression.GreaterThan(left, right);
|
||||
break;
|
||||
|
||||
case ">=":
|
||||
filter = Expression.GreaterThanOrEqual(left, right);
|
||||
break;
|
||||
case "!=":
|
||||
filter = Expression.NotEqual(left, right);
|
||||
break;
|
||||
case "contains":
|
||||
filter = Expression.Call(left, typeof(string).GetMethod("Contains", new Type[] {typeof(string)}),
|
||||
Expression.Constant(filterObj.Value));
|
||||
break;
|
||||
case "in":
|
||||
var lExp = Expression.Constant(filterObj.Value.Split(',').ToList()); //数组
|
||||
var methodInfo = typeof(List<string>).GetMethod("Contains",
|
||||
new Type[] {typeof(string)}); //Contains语句
|
||||
filter = Expression.Call(lExp, methodInfo, left);
|
||||
break;
|
||||
case "not in":
|
||||
var listExpression = Expression.Constant(filterObj.Value.Split(',').ToList()); //数组
|
||||
var method = typeof(List<string>).GetMethod("Contains", new Type[] {typeof(string)}); //Contains语句
|
||||
filter = Expression.Not(Expression.Call(listExpression, method, left));
|
||||
break;
|
||||
//交集,使用交集时左值必须时固定的值
|
||||
case "intersect": //交集
|
||||
if (property != null)
|
||||
{
|
||||
throw new Exception("交集模式下,表达式左边不能为变量,请调整数据规则,如:c=>\"A,B,C\" intersect \"B,D\"");
|
||||
}
|
||||
|
||||
var rightval = filterObj.Value.Split(',').ToList();
|
||||
var leftval = filterObj.Key.Split(',').ToList();
|
||||
var val = rightval.Intersect(leftval);
|
||||
|
||||
filter = Expression.Constant(val.Count() > 0);
|
||||
break;
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
public static Expression<Func<T, bool>> GenerateTypeBody<T>(this ParameterExpression param, Filter filterObj)
|
||||
{
|
||||
return (Expression<Func<T, bool>>) (param.GenerateBody<T>(filterObj));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建完整的lambda
|
||||
/// </summary>
|
||||
public static LambdaExpression GenerateLambda(this ParameterExpression param, Expression body)
|
||||
{
|
||||
//c=>c.XXX=="XXX"
|
||||
return Expression.Lambda(body, param);
|
||||
}
|
||||
|
||||
public static Expression<Func<T, bool>> GenerateTypeLambda<T>(this ParameterExpression param, Expression body)
|
||||
{
|
||||
return (Expression<Func<T, bool>>) (param.GenerateLambda(body));
|
||||
}
|
||||
|
||||
public static Expression AndAlso(this Expression expression, Expression expressionRight)
|
||||
{
|
||||
return Expression.AndAlso(expression, expressionRight);
|
||||
}
|
||||
|
||||
public static Expression Or(this Expression expression, Expression expressionRight)
|
||||
{
|
||||
return Expression.Or(expression, expressionRight);
|
||||
}
|
||||
|
||||
public static Expression And(this Expression expression, Expression expressionRight)
|
||||
{
|
||||
return Expression.And(expression, expressionRight);
|
||||
}
|
||||
|
||||
public static IQueryable<T> GenerateFilter<T>(this IQueryable<T> query, string parametername, string filterjson)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(filterjson))
|
||||
{
|
||||
var filterGroup = JsonHelper.Instance.Deserialize<FilterGroup>(filterjson);
|
||||
query = GenerateFilter(query, parametername, filterGroup);
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换FilterGroup为Lambda表达式
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="parametername"></param>
|
||||
/// <param name="filterGroup"></param>
|
||||
/// <returns></returns>
|
||||
public static IQueryable<T> GenerateFilter<T>(this IQueryable<T> query, string parametername,
|
||||
FilterGroup filterGroup)
|
||||
{
|
||||
var param = CreateLambdaParam<T>(parametername);
|
||||
Expression result = ConvertGroup<T>(filterGroup, param);
|
||||
query = query.Where(param.GenerateTypeLambda<T>(result));
|
||||
return query;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换filtergroup为表达式
|
||||
/// </summary>
|
||||
/// <param name="filterGroup"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static Expression ConvertGroup<T>(FilterGroup filterGroup, ParameterExpression param)
|
||||
{
|
||||
if (filterGroup == null) return null;
|
||||
|
||||
if (filterGroup.Filters.Length == 1 &&(filterGroup.Children == null || !filterGroup.Children.Any())) //只有一个条件
|
||||
{
|
||||
return param.GenerateBody<T>(filterGroup.Filters[0]);
|
||||
}
|
||||
|
||||
Expression result = ConvertFilters<T>(filterGroup.Filters, param, filterGroup.Operation);
|
||||
Expression gresult = ConvertGroup<T>(filterGroup.Children, param, filterGroup.Operation);
|
||||
if (gresult == null) return result;
|
||||
if (result == null) return gresult;
|
||||
|
||||
if (filterGroup.Operation == "and")
|
||||
{
|
||||
return result.AndAlso(gresult);
|
||||
}
|
||||
else //or
|
||||
{
|
||||
return result.Or(gresult);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换FilterGroup[]为表达式,不管FilterGroup里面的Filters
|
||||
/// </summary>
|
||||
/// <param name="groups"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="operation"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
private static Expression ConvertGroup<T>(FilterGroup[] groups, ParameterExpression param, string operation)
|
||||
{
|
||||
if (groups == null || !groups.Any()) return null;
|
||||
|
||||
Expression result = ConvertGroup<T>(groups[0], param);
|
||||
|
||||
if (groups.Length == 1) return result;
|
||||
|
||||
if (operation == "and")
|
||||
{
|
||||
foreach (var filter in groups.Skip(1))
|
||||
{
|
||||
result = result.AndAlso(ConvertGroup<T>(filter, param));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var filter in groups.Skip(1))
|
||||
{
|
||||
result = result.Or(ConvertGroup<T>(filter, param));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换Filter数组为表达式
|
||||
/// </summary>
|
||||
/// <param name="filters"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="operation"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
private static Expression ConvertFilters<T>(Filter[] filters, ParameterExpression param, string operation)
|
||||
{
|
||||
if (filters == null || !filters.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Expression result = param.GenerateBody<T>(filters[0]);
|
||||
|
||||
if (filters.Length == 1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (operation == "and")
|
||||
{
|
||||
foreach (var filter in filters.Skip(1))
|
||||
{
|
||||
result = result.AndAlso(param.GenerateBody<T>(filter));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var filter in filters.Skip(1))
|
||||
{
|
||||
result = result.Or(param.GenerateBody<T>(filter));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// ***********************************************************************
|
||||
// Assembly : FairUtility
|
||||
// Author : Yubao Li
|
||||
// Created : 08-18-2015
|
||||
//
|
||||
// Last Modified By : Yubao Li
|
||||
// Last Modified On : 08-18-2015
|
||||
// ***********************************************************************
|
||||
// <copyright file="DynamicLinq.cs" company="">
|
||||
// Copyright (c) . All rights reserved.
|
||||
// </copyright>
|
||||
// <summary>动态linq</summary>
|
||||
// ***********************************************************************
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using SqlSugar;
|
||||
|
||||
namespace Infrastructure
|
||||
{
|
||||
public static class DynamicLinq
|
||||
{
|
||||
public static ParameterExpression CreateLambdaParam<T>(string name)
|
||||
{
|
||||
return Expression.Parameter(typeof(T), name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建linq表达示的body部分
|
||||
/// </summary>
|
||||
public static Expression GenerateBody<T>(this ParameterExpression param, Filter filterObj)
|
||||
{
|
||||
PropertyInfo property = typeof(T).GetProperty(filterObj.Key);
|
||||
|
||||
Expression left = null; //组装左边
|
||||
//组装右边
|
||||
Expression right = null;
|
||||
|
||||
if (property != null)
|
||||
{
|
||||
left = Expression.Property(param, property);
|
||||
if (property.PropertyType == typeof(int))
|
||||
{
|
||||
right = Expression.Constant(int.Parse(filterObj.Value));
|
||||
}
|
||||
else if (property.PropertyType == typeof(DateTime))
|
||||
{
|
||||
right = Expression.Constant(DateTime.Parse(filterObj.Value));
|
||||
}
|
||||
else if (property.PropertyType == typeof(string))
|
||||
{
|
||||
right = Expression.Constant(filterObj.Value);
|
||||
}
|
||||
else if (property.PropertyType == typeof(decimal))
|
||||
{
|
||||
right = Expression.Constant(decimal.Parse(filterObj.Value));
|
||||
}
|
||||
else if (property.PropertyType == typeof(Guid))
|
||||
{
|
||||
right = Expression.Constant(Guid.Parse(filterObj.Value));
|
||||
}
|
||||
else if (property.PropertyType == typeof(bool))
|
||||
{
|
||||
right = Expression.Constant(filterObj.Value.Equals("1"));
|
||||
}
|
||||
else if (property.PropertyType == typeof(Guid?))
|
||||
{
|
||||
left = Expression.Property(left, "Value");
|
||||
right = Expression.Constant(Guid.Parse(filterObj.Value));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("暂不能解析该Key的类型");
|
||||
}
|
||||
}
|
||||
else //如果左边不是属性,直接是值的情况
|
||||
{
|
||||
left = Expression.Constant(filterObj.Key);
|
||||
right = Expression.Constant(filterObj.Value);
|
||||
}
|
||||
|
||||
//c.XXX=="XXX"
|
||||
Expression filter = Expression.Equal(left, right);
|
||||
switch (filterObj.Contrast)
|
||||
{
|
||||
case "<=":
|
||||
filter = Expression.LessThanOrEqual(left, right);
|
||||
break;
|
||||
|
||||
case "<":
|
||||
filter = Expression.LessThan(left, right);
|
||||
break;
|
||||
|
||||
case ">":
|
||||
filter = Expression.GreaterThan(left, right);
|
||||
break;
|
||||
|
||||
case ">=":
|
||||
filter = Expression.GreaterThanOrEqual(left, right);
|
||||
break;
|
||||
case "!=":
|
||||
filter = Expression.NotEqual(left, right);
|
||||
break;
|
||||
case "contains":
|
||||
filter = Expression.Call(left, typeof(string).GetMethod("Contains", new Type[] {typeof(string)}),
|
||||
Expression.Constant(filterObj.Value));
|
||||
break;
|
||||
case "in":
|
||||
var lExp = Expression.Constant(filterObj.Value.Split(',').ToList()); //数组
|
||||
var methodInfo = typeof(List<string>).GetMethod("Contains",
|
||||
new Type[] {typeof(string)}); //Contains语句
|
||||
filter = Expression.Call(lExp, methodInfo, left);
|
||||
break;
|
||||
case "not in":
|
||||
var listExpression = Expression.Constant(filterObj.Value.Split(',').ToList()); //数组
|
||||
var method = typeof(List<string>).GetMethod("Contains", new Type[] {typeof(string)}); //Contains语句
|
||||
filter = Expression.Not(Expression.Call(listExpression, method, left));
|
||||
break;
|
||||
//交集,使用交集时左值必须时固定的值
|
||||
case "intersect": //交集
|
||||
if (property != null)
|
||||
{
|
||||
throw new Exception("交集模式下,表达式左边不能为变量,请调整数据规则,如:c=>\"A,B,C\" intersect \"B,D\"");
|
||||
}
|
||||
|
||||
var rightval = filterObj.Value.Split(',').ToList();
|
||||
var leftval = filterObj.Key.Split(',').ToList();
|
||||
var val = rightval.Intersect(leftval);
|
||||
|
||||
filter = Expression.Constant(val.Count() > 0);
|
||||
break;
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
public static Expression<Func<T, bool>> GenerateTypeBody<T>(this ParameterExpression param, Filter filterObj)
|
||||
{
|
||||
return (Expression<Func<T, bool>>) (param.GenerateBody<T>(filterObj));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建完整的lambda
|
||||
/// </summary>
|
||||
public static LambdaExpression GenerateLambda(this ParameterExpression param, Expression body)
|
||||
{
|
||||
//c=>c.XXX=="XXX"
|
||||
return Expression.Lambda(body, param);
|
||||
}
|
||||
|
||||
public static Expression<Func<T, bool>> GenerateTypeLambda<T>(this ParameterExpression param, Expression body)
|
||||
{
|
||||
return (Expression<Func<T, bool>>) (param.GenerateLambda(body));
|
||||
}
|
||||
|
||||
public static Expression AndAlso(this Expression expression, Expression expressionRight)
|
||||
{
|
||||
return Expression.AndAlso(expression, expressionRight);
|
||||
}
|
||||
|
||||
public static Expression Or(this Expression expression, Expression expressionRight)
|
||||
{
|
||||
return Expression.Or(expression, expressionRight);
|
||||
}
|
||||
|
||||
public static Expression And(this Expression expression, Expression expressionRight)
|
||||
{
|
||||
return Expression.And(expression, expressionRight);
|
||||
}
|
||||
|
||||
public static IQueryable<T> GenerateFilter<T>(this IQueryable<T> query, string parametername, string filterjson)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(filterjson))
|
||||
{
|
||||
var filterGroup = JsonHelper.Instance.Deserialize<FilterGroup>(filterjson);
|
||||
query = GenerateFilter(query, parametername, filterGroup);
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换FilterGroup为Lambda表达式
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="parametername"></param>
|
||||
/// <param name="filterGroup"></param>
|
||||
/// <returns></returns>
|
||||
public static IQueryable<T> GenerateFilter<T>(this IQueryable<T> query, string parametername,
|
||||
FilterGroup filterGroup)
|
||||
{
|
||||
var param = CreateLambdaParam<T>(parametername);
|
||||
Expression result = ConvertGroup<T>(filterGroup, param);
|
||||
query = query.Where(param.GenerateTypeLambda<T>(result));
|
||||
return query;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换FilterGroup为Lambda表达式
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="parametername"></param>
|
||||
/// <param name="filterGroup"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static ISugarQueryable<T> GenerateFilter<T>(this ISugarQueryable<T> query, string parametername,
|
||||
FilterGroup filterGroup)
|
||||
{
|
||||
var param = CreateLambdaParam<T>(parametername);
|
||||
Expression result = ConvertGroup<T>(filterGroup, param);
|
||||
query = query.Where(param.GenerateTypeLambda<T>(result));
|
||||
return query;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换filtergroup为表达式
|
||||
/// </summary>
|
||||
/// <param name="filterGroup"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static Expression ConvertGroup<T>(FilterGroup filterGroup, ParameterExpression param)
|
||||
{
|
||||
if (filterGroup == null) return null;
|
||||
|
||||
if (filterGroup.Filters.Length == 1 &&(filterGroup.Children == null || !filterGroup.Children.Any())) //只有一个条件
|
||||
{
|
||||
return param.GenerateBody<T>(filterGroup.Filters[0]);
|
||||
}
|
||||
|
||||
Expression result = ConvertFilters<T>(filterGroup.Filters, param, filterGroup.Operation);
|
||||
Expression gresult = ConvertGroup<T>(filterGroup.Children, param, filterGroup.Operation);
|
||||
if (gresult == null) return result;
|
||||
if (result == null) return gresult;
|
||||
|
||||
if (filterGroup.Operation == "and")
|
||||
{
|
||||
return result.AndAlso(gresult);
|
||||
}
|
||||
else //or
|
||||
{
|
||||
return result.Or(gresult);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换FilterGroup[]为表达式,不管FilterGroup里面的Filters
|
||||
/// </summary>
|
||||
/// <param name="groups"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="operation"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
private static Expression ConvertGroup<T>(FilterGroup[] groups, ParameterExpression param, string operation)
|
||||
{
|
||||
if (groups == null || !groups.Any()) return null;
|
||||
|
||||
Expression result = ConvertGroup<T>(groups[0], param);
|
||||
|
||||
if (groups.Length == 1) return result;
|
||||
|
||||
if (operation == "and")
|
||||
{
|
||||
foreach (var filter in groups.Skip(1))
|
||||
{
|
||||
result = result.AndAlso(ConvertGroup<T>(filter, param));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var filter in groups.Skip(1))
|
||||
{
|
||||
result = result.Or(ConvertGroup<T>(filter, param));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换Filter数组为表达式
|
||||
/// </summary>
|
||||
/// <param name="filters"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="operation"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
private static Expression ConvertFilters<T>(Filter[] filters, ParameterExpression param, string operation)
|
||||
{
|
||||
if (filters == null || !filters.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Expression result = param.GenerateBody<T>(filters[0]);
|
||||
|
||||
if (filters.Length == 1)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (operation == "and")
|
||||
{
|
||||
foreach (var filter in filters.Skip(1))
|
||||
{
|
||||
result = result.AndAlso(param.GenerateBody<T>(filter));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var filter in filters.Skip(1))
|
||||
{
|
||||
result = result.Or(param.GenerateBody<T>(filter));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.2" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.102" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.2.4" />
|
||||
</ItemGroup>
|
||||
|
||||
|
99
OpenAuth.App/Base/SqlSugarBaseApp.cs
Normal file
99
OpenAuth.App/Base/SqlSugarBaseApp.cs
Normal file
@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using OpenAuth.App.Interface;
|
||||
using OpenAuth.Repository.Core;
|
||||
using OpenAuth.Repository.Domain;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using SqlSugar;
|
||||
|
||||
namespace OpenAuth.App
|
||||
{
|
||||
public abstract class SqlSugarBaseApp<T>
|
||||
{
|
||||
protected ISqlSugarClient SugarClient;
|
||||
|
||||
protected IAuth _auth;
|
||||
|
||||
public SqlSugarBaseApp(ISqlSugarClient client, IAuth auth)
|
||||
{
|
||||
SugarClient = client;
|
||||
_auth = auth;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前登录用户的数据访问权限
|
||||
/// </summary>
|
||||
/// <param name="parametername">linq表达式参数的名称,如u=>u.name中的"u"</param>
|
||||
/// <returns></returns>
|
||||
protected ISugarQueryable<T> GetDataPrivilege(string parametername)
|
||||
{
|
||||
var loginUser = _auth.GetCurrentUser();
|
||||
if (loginUser.User.Account == Define.SYSTEM_USERNAME) return SugarClient.Queryable<T>(); //超级管理员特权
|
||||
|
||||
var moduleName = typeof(T).Name;
|
||||
var rule = SugarClient.Queryable<DataPrivilegeRule>().First(u => u.SourceCode == moduleName);
|
||||
if (rule == null) return SugarClient.Queryable<T>(); //没有设置数据规则,那么视为该资源允许被任何主体查看
|
||||
if (rule.PrivilegeRules.Contains(Define.DATAPRIVILEGE_LOGINUSER) ||
|
||||
rule.PrivilegeRules.Contains(Define.DATAPRIVILEGE_LOGINROLE)||
|
||||
rule.PrivilegeRules.Contains(Define.DATAPRIVILEGE_LOGINORG))
|
||||
{
|
||||
|
||||
//即把{loginUser} =='xxxxxxx'换为 loginUser.User.Id =='xxxxxxx',从而把当前登录的用户名与当时设计规则时选定的用户id对比
|
||||
rule.PrivilegeRules = rule.PrivilegeRules.Replace(Define.DATAPRIVILEGE_LOGINUSER, loginUser.User.Id);
|
||||
|
||||
var roles = loginUser.Roles.Select(u => u.Id).ToList();
|
||||
roles.Sort(); //按字母排序,这样可以进行like操作
|
||||
rule.PrivilegeRules = rule.PrivilegeRules.Replace(Define.DATAPRIVILEGE_LOGINROLE,
|
||||
string.Join(',',roles));
|
||||
|
||||
var orgs = loginUser.Orgs.Select(u => u.Id).ToList();
|
||||
orgs.Sort();
|
||||
rule.PrivilegeRules = rule.PrivilegeRules.Replace(Define.DATAPRIVILEGE_LOGINORG,
|
||||
string.Join(',',orgs));
|
||||
}
|
||||
return SugarClient.Queryable<T>().GenerateFilter(parametername,
|
||||
JsonHelper.Instance.Deserialize<FilterGroup>(rule.PrivilegeRules));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算实体更新的层级信息
|
||||
/// </summary>
|
||||
/// <typeparam name="U">U必须是一个继承TreeEntity的结构</typeparam>
|
||||
/// <param name="entity"></param>
|
||||
public void CaculateCascade<U>(U entity) where U : TreeEntity
|
||||
{
|
||||
if (entity.ParentId == "") entity.ParentId = null;
|
||||
string cascadeId;
|
||||
int currentCascadeId = 1; //当前结点的级联节点最后一位
|
||||
var sameLevels = SugarClient.Queryable<U>().Where(o => o.ParentId == entity.ParentId && o.Id != entity.Id);
|
||||
foreach (var obj in sameLevels.ToList())
|
||||
{
|
||||
int objCascadeId = int.Parse(obj.CascadeId.TrimEnd('.').Split('.').Last());
|
||||
if (currentCascadeId <= objCascadeId) currentCascadeId = objCascadeId + 1;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(entity.ParentId))
|
||||
{
|
||||
var parentOrg = SugarClient.Queryable<U>().First(o => o.Id == entity.ParentId);
|
||||
if (parentOrg != null)
|
||||
{
|
||||
cascadeId = parentOrg.CascadeId + currentCascadeId + ".";
|
||||
entity.ParentName = parentOrg.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("未能找到该组织的父节点信息");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cascadeId = ".0." + currentCascadeId + ".";
|
||||
entity.ParentName = "根节点";
|
||||
}
|
||||
|
||||
entity.CascadeId = cascadeId;
|
||||
}
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using OpenAuth.Repository.Interface;
|
||||
using SqlSugar;
|
||||
|
||||
namespace OpenAuth.Repository.Test
|
||||
{
|
||||
@ -65,6 +66,58 @@ namespace OpenAuth.Repository.Test
|
||||
serviceCollection.AddScoped(x => httpContextAccessorMock.Object);
|
||||
|
||||
serviceCollection.AddDbContext<OpenAuthDBContext>();
|
||||
|
||||
var dbtypes = config.GetSection("AppSetting:DbTypes").GetChildren()
|
||||
.ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
var connectionString = config.GetSection("ConnectionStrings")["OpenAuthDBContext"];
|
||||
Console.WriteLine($"单元测试数据库信息:{dbtypes[httpContextAccessorMock.Object.GetTenantId()]}/{connectionString}");
|
||||
|
||||
serviceCollection.AddScoped<ISqlSugarClient>(s =>
|
||||
{
|
||||
|
||||
SqlSugarClient sqlSugar;
|
||||
if(dbtypes.ContainsValue(Define.DBTYPE_SQLSERVER))
|
||||
{
|
||||
sqlSugar = new SqlSugarClient (new ConnectionConfig()
|
||||
{
|
||||
DbType = SqlSugar.DbType.SqlServer,
|
||||
ConnectionString = connectionString,
|
||||
IsAutoCloseConnection = true,
|
||||
});
|
||||
}
|
||||
else if(dbtypes.ContainsValue(Define.DBTYPE_MYSQL)) //mysql
|
||||
{
|
||||
sqlSugar = new SqlSugarClient (new ConnectionConfig()
|
||||
{
|
||||
DbType = SqlSugar.DbType.MySql,
|
||||
ConnectionString = connectionString,
|
||||
IsAutoCloseConnection = true,
|
||||
});
|
||||
}
|
||||
else if(dbtypes.ContainsValue(Define.DBTYPE_PostgreSQL)) //PostgreSQL
|
||||
{
|
||||
sqlSugar = new SqlSugarClient (new ConnectionConfig()
|
||||
{
|
||||
DbType = SqlSugar.DbType.PostgreSQL,
|
||||
ConnectionString = connectionString,
|
||||
IsAutoCloseConnection = true,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlSugar = new SqlSugarClient (new ConnectionConfig()
|
||||
{
|
||||
DbType = SqlSugar.DbType.Oracle,
|
||||
ConnectionString = connectionString,
|
||||
IsAutoCloseConnection = true,
|
||||
});
|
||||
}
|
||||
|
||||
return sqlSugar;
|
||||
});
|
||||
|
||||
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
|
||||
@ -75,12 +128,6 @@ namespace OpenAuth.Repository.Test
|
||||
|
||||
var _container = builder.Build();
|
||||
_autofacServiceProvider = new AutofacServiceProvider(_container);
|
||||
|
||||
var dbtypes = config.GetSection("AppSetting:DbTypes").GetChildren()
|
||||
.ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
Console.WriteLine($"单元测试数据库信息:{dbtypes[httpContextAccessorMock.Object.GetTenantId()]}/{config.GetSection("ConnectionStrings")["OpenAuthDBContext"]}");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
93
OpenAuth.Repository/Test/TestSugarDynamicLinq.cs
Normal file
93
OpenAuth.Repository/Test/TestSugarDynamicLinq.cs
Normal file
@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Infrastructure;
|
||||
using NUnit.Framework;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace OpenAuth.Repository.Test
|
||||
{
|
||||
class TestSugarDynamicLinq : TestBase
|
||||
{
|
||||
[Test]
|
||||
public void GenerateFilter()
|
||||
{
|
||||
var dbcontext = _autofacServiceProvider.GetService<OpenAuthDBContext>();
|
||||
var json = @"
|
||||
{
|
||||
""Operation"": ""and"",
|
||||
""Filters"": [{
|
||||
""Key"": ""Name"",
|
||||
""Contrast"": ""=="",
|
||||
""Value"": ""admin""
|
||||
|
||||
},
|
||||
{
|
||||
""Key"": ""Name"",
|
||||
""Contrast"": ""=="",
|
||||
""Value"": ""admin""
|
||||
}
|
||||
],
|
||||
""Children"": [{
|
||||
""Operation"": ""or"",
|
||||
""Filters"": [{
|
||||
""Key"": ""Name"",
|
||||
""Contrast"": ""=="",
|
||||
""Value"": ""admin""
|
||||
},
|
||||
{
|
||||
""Key"": ""Name"",
|
||||
""Contrast"": ""=="",
|
||||
""Value"": ""admin""
|
||||
}
|
||||
],
|
||||
""Children"": [
|
||||
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
";
|
||||
|
||||
var query = dbcontext.Users.GenerateFilter("c",json);
|
||||
Console.WriteLine(query.Expression.ToString());
|
||||
|
||||
Console.WriteLine(JsonHelper.Instance.Serialize(query.ToList()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDynamic()
|
||||
{
|
||||
FilterGroup sub = new FilterGroup
|
||||
{
|
||||
Operation = "or"
|
||||
};
|
||||
sub.Filters = new[]
|
||||
{
|
||||
new Filter {Key = "Name", Value = "name", Contrast = "=="},
|
||||
new Filter {Key = "Sex", Value = "10", Contrast = "=="}
|
||||
};
|
||||
|
||||
FilterGroup filterGroup = new FilterGroup
|
||||
{
|
||||
Operation = "and"
|
||||
};
|
||||
filterGroup.Filters = new[]
|
||||
{
|
||||
new Filter {Key = "Account", Value = "name", Contrast = "=="},
|
||||
new Filter {Key = "Password", Value = "10", Contrast = "=="}
|
||||
};
|
||||
|
||||
filterGroup.Children = new[]
|
||||
{
|
||||
sub
|
||||
};
|
||||
|
||||
var dbcontext = _autofacServiceProvider.GetService<OpenAuthDBContext>();
|
||||
|
||||
var query = dbcontext.Users.GenerateFilter("c",JsonHelper.Instance.Serialize(filterGroup));
|
||||
Console.WriteLine(query.Expression.ToString());
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ using OpenAuth.App;
|
||||
using OpenAuth.App.HostedService;
|
||||
using OpenAuth.Repository;
|
||||
using OpenAuth.WebApi.Model;
|
||||
using SqlSugar;
|
||||
using Swashbuckle.AspNetCore.SwaggerUI;
|
||||
|
||||
namespace OpenAuth.WebApi
|
||||
@ -172,6 +173,50 @@ namespace OpenAuth.WebApi
|
||||
services.AddHttpClient();
|
||||
|
||||
services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(Configuration["DataProtection"]));
|
||||
|
||||
services.AddScoped<ISqlSugarClient>(s =>
|
||||
{
|
||||
|
||||
SqlSugarClient sqlSugar;
|
||||
if(dbtypes.ContainsValue(Define.DBTYPE_SQLSERVER))
|
||||
{
|
||||
sqlSugar = new SqlSugarClient (new ConnectionConfig()
|
||||
{
|
||||
DbType = SqlSugar.DbType.SqlServer,
|
||||
ConnectionString = connectionString,
|
||||
IsAutoCloseConnection = true,
|
||||
});
|
||||
}
|
||||
else if(dbtypes.ContainsValue(Define.DBTYPE_MYSQL)) //mysql
|
||||
{
|
||||
sqlSugar = new SqlSugarClient (new ConnectionConfig()
|
||||
{
|
||||
DbType = SqlSugar.DbType.MySql,
|
||||
ConnectionString = connectionString,
|
||||
IsAutoCloseConnection = true,
|
||||
});
|
||||
}
|
||||
else if(dbtypes.ContainsValue(Define.DBTYPE_PostgreSQL)) //PostgreSQL
|
||||
{
|
||||
sqlSugar = new SqlSugarClient (new ConnectionConfig()
|
||||
{
|
||||
DbType = SqlSugar.DbType.PostgreSQL,
|
||||
ConnectionString = connectionString,
|
||||
IsAutoCloseConnection = true,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlSugar = new SqlSugarClient (new ConnectionConfig()
|
||||
{
|
||||
DbType = SqlSugar.DbType.Oracle,
|
||||
ConnectionString = connectionString,
|
||||
IsAutoCloseConnection = true,
|
||||
});
|
||||
}
|
||||
|
||||
return sqlSugar;
|
||||
});
|
||||
|
||||
|
||||
//设置定时启动的任务
|
||||
@ -232,7 +277,7 @@ namespace OpenAuth.WebApi
|
||||
app.UseSwaggerUI(c =>
|
||||
{
|
||||
c.IndexStream = () =>
|
||||
GetType().GetTypeInfo().Assembly.GetManifestResourceStream("OpenAuth.WebApi.index.html");
|
||||
IntrospectionExtensions.GetTypeInfo(GetType()).Assembly.GetManifestResourceStream("OpenAuth.WebApi.index.html");
|
||||
|
||||
foreach (var controller in GetControllers())
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user