boxu.zheng
1 year ago
13 changed files with 753 additions and 33 deletions
@ -0,0 +1,8 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.Application.Dtos; |
||||
|
|
||||
|
namespace Faster.Zheng.Winin.AppBase.CreateUpdateBaseDto; |
||||
|
|
||||
|
public class CreateUpdateBaseDto : EntityDto<Guid> |
||||
|
{ |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace Faster.Zheng.Winin.AppBase.Filters; |
||||
|
|
||||
|
public class Condition |
||||
|
{ |
||||
|
public ICollection<Filter> Filters { get; set; } = new List<Filter>(); |
||||
|
} |
@ -0,0 +1,62 @@ |
|||||
|
using System.ComponentModel; |
||||
|
|
||||
|
namespace Faster.Zheng.Winin.AppBase.Filters; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 过滤条件
|
||||
|
/// </summary>
|
||||
|
public enum EnumFilterAction |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// equal
|
||||
|
/// </summary>
|
||||
|
[Description("等于")] Equal = 0, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Not equal
|
||||
|
/// </summary>
|
||||
|
[Description("不等于")] NotEqual = 1, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Bigger
|
||||
|
/// </summary>
|
||||
|
[Description("大于")] BiggerThan = 2, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Smaller
|
||||
|
/// </summary>
|
||||
|
[Description("小于")] SmallThan = 3, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Bigger or equal
|
||||
|
/// </summary>
|
||||
|
[Description("大于等于")] BiggerThanOrEqual = 4, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Small or equal
|
||||
|
/// </summary>
|
||||
|
[Description("小于等于")] SmallThanOrEqual = 5, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Like
|
||||
|
/// </summary>
|
||||
|
[Description("类似于")] Like = 6, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Not like
|
||||
|
/// </summary>
|
||||
|
[Description("不类似于")] NotLike = 7, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Contained in
|
||||
|
/// List<string > items = new List<string>();
|
||||
|
/// string value = JsonSerializer.Serialize(items);//转成Json字符串
|
||||
|
/// FilterCondition filterCondition = new FilterCondition() { Column = "Name", Value = value, Action = EnumFilterAction.In, Logic = EnumFilterLogic.And };
|
||||
|
/// </summary>
|
||||
|
[Description("包含于")] In = 8, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Not contained in
|
||||
|
/// </summary>
|
||||
|
[Description("不包含于")] NotIn = 9, |
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
namespace Faster.Zheng.Winin.AppBase.Filters; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 过滤逻辑
|
||||
|
/// </summary>
|
||||
|
public enum EnumFilterLogic |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 与
|
||||
|
/// </summary>
|
||||
|
And = 0, |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 或
|
||||
|
/// </summary>
|
||||
|
Or = 1 |
||||
|
} |
@ -0,0 +1,40 @@ |
|||||
|
namespace Faster.Zheng.Winin.AppBase.Filters; |
||||
|
|
||||
|
public class Filter |
||||
|
{ |
||||
|
public Filter() |
||||
|
{ |
||||
|
Logic = "And"; |
||||
|
} |
||||
|
|
||||
|
public Filter(string column, string value, |
||||
|
string action = "==", |
||||
|
string logic = "And") |
||||
|
{ |
||||
|
Column = column; |
||||
|
Action = action; |
||||
|
Value = value; |
||||
|
Logic = logic; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 过滤条件之间的逻辑关系:AND和OR
|
||||
|
/// </summary>
|
||||
|
public string Logic { get; set; } = "And"; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 过滤条件中使用的数据列
|
||||
|
/// </summary>
|
||||
|
public string Column { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 过滤条件中的操作:==,!=,>,<,>=,<=,In,NotIn,Like,NotLike
|
||||
|
/// Equal、NotEqual、BiggerThan、SmallThan、BiggerThanOrEqual、SmallThanOrEqual、In、NotIn
|
||||
|
/// </summary>
|
||||
|
public string Action { get; set; } = "=="; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 过滤条件中的操作的值
|
||||
|
/// </summary>
|
||||
|
public string Value { get; set; } |
||||
|
} |
@ -0,0 +1,336 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Globalization; |
||||
|
using System.Linq; |
||||
|
using System.Linq.Expressions; |
||||
|
using System.Text.Json; |
||||
|
using Volo.Abp; |
||||
|
|
||||
|
namespace Faster.Zheng.Winin.AppBase.Filters; |
||||
|
|
||||
|
public static class FilterExtensions |
||||
|
{ |
||||
|
public static Expression<Func<T, bool>> ToLambda<T>(this string jsonFilter) |
||||
|
{ |
||||
|
if (string.IsNullOrWhiteSpace(jsonFilter)) |
||||
|
{ |
||||
|
return p => true; |
||||
|
} |
||||
|
|
||||
|
var filterConditions = JsonSerializer.Deserialize<List<Filter>>(jsonFilter); |
||||
|
return filterConditions.ToLambda<T>(); |
||||
|
} |
||||
|
|
||||
|
public static Expression<Func<T, bool>> ToLambda<T>(this Filter filter) |
||||
|
{ |
||||
|
var filterConditions = new List<Filter> { filter }; |
||||
|
return filterConditions.ToLambda<T>(); |
||||
|
} |
||||
|
|
||||
|
public static Expression<Func<T, bool>> ToLambda<T>(this ICollection<Filter> filterConditionList) |
||||
|
{ |
||||
|
Expression<Func<T, bool>> condition = null; |
||||
|
try |
||||
|
{ |
||||
|
if (!filterConditionList.Any()) |
||||
|
{ |
||||
|
//创建默认表达式
|
||||
|
return p => true; |
||||
|
} |
||||
|
|
||||
|
foreach (var filterCondition in filterConditionList) |
||||
|
{ |
||||
|
var tempCondition = CreateLambda<T>(filterCondition); |
||||
|
if (condition == null) |
||||
|
{ |
||||
|
condition = tempCondition; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
condition = filterCondition.Logic switch |
||||
|
{ |
||||
|
"And" => condition.And(tempCondition), |
||||
|
"Or" => condition.Or(tempCondition), |
||||
|
_ => condition |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
throw new Exception($"获取筛选条件异常:{ex.Message}"); |
||||
|
} |
||||
|
|
||||
|
return condition; |
||||
|
} |
||||
|
|
||||
|
private static Expression<Func<T, bool>> CreateLambda<T>(Filter filter) |
||||
|
{ |
||||
|
Expression<Func<T, bool>> expression = p => false; |
||||
|
try |
||||
|
{ |
||||
|
var parameter = Expression.Parameter(typeof(T), "p"); //创建参数p
|
||||
|
var member = Expression.PropertyOrField(parameter, filter.Column); //创建表达式中的属性或字段
|
||||
|
// var propertyType = member.Type; //取属性类型,常量constant按此类型进行转换
|
||||
|
//var constant = Expression.Constant(filterCondition.Value);//创建常数
|
||||
|
|
||||
|
ConstantExpression constant = null; |
||||
|
if (filter.Action != "In" && filter.Action != "NotIn") |
||||
|
{ |
||||
|
constant = CreateConstantExpression(member.Type, filter.Value); |
||||
|
} |
||||
|
|
||||
|
switch (filter.Action.ToLower()) |
||||
|
{ |
||||
|
case "==": |
||||
|
expression = Expression.Lambda<Func<T, bool>>(Expression.Equal(member, constant), parameter); |
||||
|
break; |
||||
|
|
||||
|
case "!=": |
||||
|
expression = Expression.Lambda<Func<T, bool>>(Expression.NotEqual(member, constant), parameter); |
||||
|
break; |
||||
|
|
||||
|
case ">": |
||||
|
expression = Expression.Lambda<Func<T, bool>>(Expression.GreaterThan(member, constant), parameter); |
||||
|
break; |
||||
|
|
||||
|
case "<": |
||||
|
expression = Expression.Lambda<Func<T, bool>>(Expression.LessThan(member, constant), parameter); |
||||
|
break; |
||||
|
|
||||
|
case ">=": |
||||
|
expression = |
||||
|
Expression.Lambda<Func<T, bool>>(Expression.GreaterThanOrEqual(member, constant), parameter); |
||||
|
break; |
||||
|
|
||||
|
case "<=": |
||||
|
expression = |
||||
|
Expression.Lambda<Func<T, bool>>(Expression.LessThanOrEqual(member, constant), parameter); |
||||
|
break; |
||||
|
|
||||
|
case "like": |
||||
|
expression = GetExpressionLikeMethod<T>("Contains", filter); |
||||
|
break; |
||||
|
|
||||
|
case "notlike": |
||||
|
expression = GetExpressionNotLikeMethod<T>("Contains", filter); |
||||
|
break; |
||||
|
|
||||
|
case "in": |
||||
|
expression = GetExpressionInMethod<T>("Contains", member.Type, filter); |
||||
|
break; |
||||
|
|
||||
|
case "notin": |
||||
|
expression = GetExpressionNotInMethod<T>("Contains", member.Type, filter); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
throw new UserFriendlyException(ex.Message); |
||||
|
} |
||||
|
|
||||
|
return expression; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// </summary>
|
||||
|
/// <param name="propertyType"></param>
|
||||
|
/// <param name="value"></param>
|
||||
|
/// <returns></returns>
|
||||
|
private static ConstantExpression CreateConstantExpression(Type propertyType, string value) |
||||
|
{ |
||||
|
ConstantExpression constant; |
||||
|
try |
||||
|
{ |
||||
|
if (propertyType.IsGenericType && |
||||
|
propertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) |
||||
|
{ |
||||
|
var objValue = Convert.ChangeType(value, propertyType.GetGenericArguments()[0], |
||||
|
CultureInfo.InvariantCulture); |
||||
|
constant = Expression.Constant(objValue); |
||||
|
} |
||||
|
else if (propertyType.IsEnum) |
||||
|
{ |
||||
|
var enumValue = (Enum)Enum.Parse(propertyType, value, true); |
||||
|
constant = Expression.Constant(enumValue); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
constant = propertyType.Name switch |
||||
|
{ |
||||
|
"Guid" => Expression.Constant(Guid.Parse(value)), |
||||
|
_ => Expression.Constant(Convert.ChangeType(value, propertyType, CultureInfo.InvariantCulture)) |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
throw new Exception($"获取ConstantExpression异常:{ex.Message}"); |
||||
|
} |
||||
|
|
||||
|
return constant; |
||||
|
} |
||||
|
|
||||
|
private static Expression<Func<T, bool>> GetExpressionLikeMethod<T>(string methodName, Filter filter) |
||||
|
{ |
||||
|
var parameterExpression = Expression.Parameter(typeof(T), "p"); |
||||
|
// MethodCallExpression methodExpression = GetMethodExpression(methodName, filterCondition.Column, filterCondition.Value, parameterExpression);
|
||||
|
var methodExpression = GetMethodExpression(methodName, filter.Column, filter.Value, |
||||
|
parameterExpression); |
||||
|
return Expression.Lambda<Func<T, bool>>(methodExpression, parameterExpression); |
||||
|
} |
||||
|
|
||||
|
private static Expression<Func<T, bool>> GetExpressionNotLikeMethod<T>(string methodName, Filter filter) |
||||
|
{ |
||||
|
var parameterExpression = Expression.Parameter(typeof(T), "p"); |
||||
|
var methodExpression = GetMethodExpression(methodName, filter.Column, filter.Value, |
||||
|
parameterExpression); |
||||
|
var notMethodExpression = Expression.Not(methodExpression); |
||||
|
return Expression.Lambda<Func<T, bool>>(notMethodExpression, parameterExpression); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 生成guidList.Contains(p=>p.GUId);
|
||||
|
/// 除String类型,其他类型涉及到类型转换.如GUID
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T"></typeparam>
|
||||
|
/// <param name="methodName">Contains</param>
|
||||
|
/// <param name="propertyType">PropertyType/typeof(GUId)</param>
|
||||
|
/// <param name="filter">PropertyName/PropertyValue</param>
|
||||
|
/// <returns></returns>
|
||||
|
private static Expression<Func<T, bool>> GetExpressionInMethod<T>(string methodName, Type propertyType, |
||||
|
Filter filter) |
||||
|
{ |
||||
|
var parameterExpression = Expression.Parameter(typeof(T), "p"); |
||||
|
var lstType = typeof(List<>).MakeGenericType(propertyType); |
||||
|
|
||||
|
//转换枚举
|
||||
|
//if (propertyType.IsEnum)
|
||||
|
//{
|
||||
|
// var valueArrayStrings = JsonSerializer.Deserialize<List<string>>(filter.Value);
|
||||
|
// List<object> newValues = new List<object>();
|
||||
|
|
||||
|
// var enumValues = propertyType.GetEnumValues();
|
||||
|
|
||||
|
// foreach (var valueArray in valueArrayStrings)
|
||||
|
// {
|
||||
|
// foreach (var enumValue in enumValues)
|
||||
|
// {
|
||||
|
// if (enumValue.ToString() == valueArray)
|
||||
|
// {
|
||||
|
// newValues.Add(enumValue);
|
||||
|
// break;
|
||||
|
// }
|
||||
|
// }
|
||||
|
// }
|
||||
|
// var newValue = JsonSerializer.Serialize(newValues);
|
||||
|
// filter.Value = newValue;
|
||||
|
//}
|
||||
|
|
||||
|
var propertyValue = JsonSerializer.Deserialize($"{filter.Value}", lstType); |
||||
|
if (propertyValue != null) |
||||
|
{ |
||||
|
var methodExpression = GetListMethodExpression(methodName, propertyType, filter.Column, propertyValue, |
||||
|
parameterExpression); |
||||
|
var expression = Expression.Lambda<Func<T, bool>>(methodExpression, parameterExpression); |
||||
|
return expression; |
||||
|
} |
||||
|
|
||||
|
return p => false; |
||||
|
} |
||||
|
|
||||
|
private static Expression<Func<T, bool>> GetExpressionNotInMethod<T>(string methodName, Type propertyType, |
||||
|
Filter filter) |
||||
|
{ |
||||
|
var parameterExpression = Expression.Parameter(typeof(T), "p"); |
||||
|
var lstType = typeof(List<>).MakeGenericType(propertyType); |
||||
|
var propertyValue = JsonSerializer.Deserialize(filter.Value, lstType); |
||||
|
if (propertyValue != null) |
||||
|
{ |
||||
|
var methodExpression = GetListMethodExpression(methodName, propertyType, filter.Column, propertyValue, |
||||
|
parameterExpression); |
||||
|
var notMethodExpression = Expression.Not(methodExpression); |
||||
|
return Expression.Lambda<Func<T, bool>>(notMethodExpression, parameterExpression); |
||||
|
} |
||||
|
|
||||
|
return p => false; |
||||
|
} |
||||
|
|
||||
|
private static MethodCallExpression GetListMethodExpression(string methodName, Type propertyType, |
||||
|
string propertyName, object propertyValue, ParameterExpression parameterExpression) |
||||
|
{ |
||||
|
var propertyExpression = Expression.Property(parameterExpression, propertyName); //p.GUID
|
||||
|
var type = typeof(List<>).MakeGenericType(propertyType); |
||||
|
var method = type.GetMethod(methodName); //获取 List.Contains()
|
||||
|
var someValue = Expression.Constant(propertyValue); //Value
|
||||
|
return Expression.Call(someValue, method, propertyExpression); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 生成类似于p=>p.Code.Contains("xxx");的lambda表达式
|
||||
|
/// parameterExpression标识p,propertyName表示values,propertyValue表示"Code",methodName表示Contains
|
||||
|
/// 仅处理p的属性类型为string这种情况
|
||||
|
/// </summary>
|
||||
|
/// <param name="methodName"></param>
|
||||
|
/// <param name="propertyName"></param>
|
||||
|
/// <param name="propertyValue"></param>
|
||||
|
/// <param name="parameterExpression"></param>
|
||||
|
/// <returns></returns>
|
||||
|
private static MethodCallExpression GetMethodExpression(string methodName, string propertyName, |
||||
|
string propertyValue, ParameterExpression parameterExpression) |
||||
|
{ |
||||
|
var propertyExpression = Expression.Property(parameterExpression, propertyName); |
||||
|
var method = typeof(string).GetMethod(methodName, new[] { typeof(string) }); |
||||
|
var someValue = Expression.Constant(propertyValue, typeof(string)); |
||||
|
return Expression.Call(propertyExpression, method, someValue); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 默认True条件
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T"></typeparam>
|
||||
|
/// <returns></returns>
|
||||
|
public static Expression<Func<T, bool>> True<T>() |
||||
|
{ |
||||
|
return f => true; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 默认False条件
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T"></typeparam>
|
||||
|
/// <returns></returns>
|
||||
|
public static Expression<Func<T, bool>> False<T>() |
||||
|
{ |
||||
|
return f => false; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 拼接 OR 条件
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T"></typeparam>
|
||||
|
/// <param name="exp"></param>
|
||||
|
/// <param name="condition"></param>
|
||||
|
/// <returns></returns>
|
||||
|
private static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> exp, |
||||
|
Expression<Func<T, bool>> condition) |
||||
|
{ |
||||
|
var inv = Expression.Invoke(condition, exp.Parameters); |
||||
|
return Expression.Lambda<Func<T, bool>>(Expression.Or(exp.Body, inv), exp.Parameters); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 拼接And条件
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T"></typeparam>
|
||||
|
/// <param name="exp"></param>
|
||||
|
/// <param name="condition"></param>
|
||||
|
/// <returns></returns>
|
||||
|
private static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> exp, |
||||
|
Expression<Func<T, bool>> condition) |
||||
|
{ |
||||
|
var inv = Expression.Invoke(condition, exp.Parameters); |
||||
|
return Expression.Lambda<Func<T, bool>>(Expression.And(exp.Body, inv), exp.Parameters); |
||||
|
} |
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
using Faster.Zheng.Winin.AppBase.Filters; |
||||
|
using Volo.Abp.Application.Dtos; |
||||
|
|
||||
|
namespace Faster.Zheng.Winin.AppBase; |
||||
|
|
||||
|
public interface ISfsRequest : IPagedAndSortedResultRequest |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 条件
|
||||
|
/// </summary>
|
||||
|
public Condition Condition { get; set; } |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Faster.Zheng.Winin.AppBase; |
||||
|
|
||||
|
public interface IZbxBase<TEntity, TEntityDto, TPagedAndSortedResultRequestDto, TKey, TCreateInput, TUpdateInput> |
||||
|
{ |
||||
|
Task<List<TEntity>> GetPageListByFilterAsync(SfsRequestInputBase sfsRequestInputBase, |
||||
|
bool includeDetails = false, CancellationToken cancellationToken = default); |
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
using Faster.Zheng.Winin.AppBase.Filters; |
||||
|
using Volo.Abp.Application.Dtos; |
||||
|
|
||||
|
namespace Faster.Zheng.Winin.AppBase; |
||||
|
|
||||
|
public class SfsRequestInputBase : PagedAndSortedResultRequestDto, ISfsRequest |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 条件
|
||||
|
/// </summary>
|
||||
|
public Condition Condition { get; set; } = new(); |
||||
|
} |
@ -0,0 +1,213 @@ |
|||||
|
using System; |
||||
|
using System.Collections; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Linq.Dynamic.Core; |
||||
|
using System.Linq.Expressions; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Faster.Zheng.Winin.AppBase.Filters; |
||||
|
using Microsoft.EntityFrameworkCore; |
||||
|
using Volo.Abp.Application.Dtos; |
||||
|
using Volo.Abp.Application.Services; |
||||
|
using Volo.Abp.Domain.Entities; |
||||
|
using Volo.Abp.Domain.Repositories; |
||||
|
|
||||
|
namespace Faster.Zheng.Winin.AppBase; |
||||
|
|
||||
|
public class ZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto, TCreateInput, TUpdateInput> : |
||||
|
CrudAppService<TEntity, TEntityDto, TKey, |
||||
|
TPagedAndSortedResultRequestDto, TCreateInput, TUpdateInput>, |
||||
|
IZbxBase<TEntity, TEntityDto, TKey, TPagedAndSortedResultRequestDto, TCreateInput, TUpdateInput> |
||||
|
where TEntity : class, IEntity<TKey> |
||||
|
where TEntityDto : IEntityDto<TKey> |
||||
|
{ |
||||
|
private IRepository<TEntity, TKey> _repository; |
||||
|
|
||||
|
public ZbxBase(IRepository<TEntity, TKey> repository) : base(repository) |
||||
|
{ |
||||
|
_repository = repository; |
||||
|
} |
||||
|
|
||||
|
#region 公开接口
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 分页查询
|
||||
|
/// </summary>
|
||||
|
/// <param name="sfsRequestInputBase"></param>
|
||||
|
/// <param name="includeDetails"></param>
|
||||
|
/// <param name="cancellationToken"></param>
|
||||
|
/// <returns></returns>
|
||||
|
//[HttpPost]
|
||||
|
public async Task<List<TEntity>> GetPageListByFilterAsync(SfsRequestInputBase sfsRequestInputBase, |
||||
|
bool includeDetails = false, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var expression = sfsRequestInputBase.Condition.Filters?.Count > 0 |
||||
|
? sfsRequestInputBase.Condition.Filters.ToLambda<TEntity>() |
||||
|
: p => true; |
||||
|
|
||||
|
var result = await GetQueryListAsync(expression, sfsRequestInputBase.SkipCount, |
||||
|
sfsRequestInputBase.MaxResultCount, |
||||
|
sfsRequestInputBase.Sorting, includeDetails, cancellationToken); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
//[HttpPost]
|
||||
|
public override async Task<TEntityDto> CreateAsync(TCreateInput input) |
||||
|
{ |
||||
|
await CheckCreatePolicyAsync(); |
||||
|
var entity = await MapToEntityAsync(input); |
||||
|
|
||||
|
//判断id是否是00000-0000 如果是则赋值
|
||||
|
var mainId = (Guid)entity.GetType().GetProperty("Id")?.GetValue(entity)!; |
||||
|
if (mainId == Guid.Empty) |
||||
|
{ |
||||
|
mainId = Guid.NewGuid(); |
||||
|
entity.GetType().GetProperty("Id")?.SetValue(entity, mainId); |
||||
|
} |
||||
|
|
||||
|
#region 给所有字表的 Id和MasterId赋值 否则默认的会是000000-000-....的id 插入时会报错
|
||||
|
|
||||
|
var propertyInfos = entity.GetType().GetProperties(); |
||||
|
foreach (var propertyInfo in propertyInfos) |
||||
|
{ |
||||
|
//判断是否是List集合
|
||||
|
if (propertyInfo.Name == "Details" |
||||
|
&& propertyInfo.PropertyType.IsGenericType |
||||
|
&& propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>)) |
||||
|
{ |
||||
|
var listProperty = typeof(TEntity).GetProperty("Details"); |
||||
|
|
||||
|
// 获取 List 的元素类型
|
||||
|
if (listProperty != null) |
||||
|
{ |
||||
|
var listItemType = listProperty.PropertyType.GetGenericArguments()[0]; |
||||
|
|
||||
|
// 获取元素类型的 ID 属性
|
||||
|
var detailIdProperty = listItemType.GetProperty("Id"); |
||||
|
var masterIdProperty = listItemType.GetProperty("MasterId"); |
||||
|
|
||||
|
if (detailIdProperty != null) |
||||
|
{ |
||||
|
// 获取 List 属性的值
|
||||
|
var list = (IList)listProperty.GetValue(entity); |
||||
|
|
||||
|
// 遍历 List 集合中的每个元素,给 ID 属性赋值
|
||||
|
if (list != null) |
||||
|
{ |
||||
|
foreach (var item in list) |
||||
|
{ |
||||
|
if ((Guid)detailIdProperty.GetValue(item)! == Guid.Empty) |
||||
|
{ |
||||
|
detailIdProperty.SetValue(item, Guid.NewGuid()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (masterIdProperty != null) |
||||
|
{ |
||||
|
// 获取 List 属性的值
|
||||
|
var list = (IList)listProperty.GetValue(entity); |
||||
|
|
||||
|
// 遍历 List 集合中的每个元素,给 ID 属性赋值
|
||||
|
if (list != null) |
||||
|
{ |
||||
|
foreach (var item in list) |
||||
|
{ |
||||
|
masterIdProperty.SetValue(item, mainId); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
TryToSetTenantId(entity); |
||||
|
await Repository.InsertAsync(entity, true); |
||||
|
return await MapToGetOutputDtoAsync(entity); |
||||
|
} |
||||
|
|
||||
|
//[HttpDelete]
|
||||
|
public override async Task DeleteAsync(TKey id) |
||||
|
{ |
||||
|
await _repository.DeleteAsync(id); |
||||
|
} |
||||
|
|
||||
|
//[HttpPut]
|
||||
|
public override Task<TEntityDto> UpdateAsync(TKey id, TUpdateInput input) |
||||
|
{ |
||||
|
return base.UpdateAsync(id, input); |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
|
||||
|
#region 私有处理
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// 按表达式条件获取分页列表
|
||||
|
/// </summary>
|
||||
|
/// <param name="expression"></param>
|
||||
|
/// <param name="skipCount"></param>
|
||||
|
/// <param name="maxResultCount"></param>
|
||||
|
/// <param name="sorting"></param>
|
||||
|
/// <param name="includeDetails"></param>
|
||||
|
/// <param name="cancellationToken"></param>
|
||||
|
/// <returns></returns>
|
||||
|
private async Task<List<TEntity>> GetQueryListAsync(Expression<Func<TEntity, bool>> expression, |
||||
|
int skipCount, int maxResultCount, string sorting, |
||||
|
bool includeDetails = false, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var query = await Repository.GetQueryableAsync(); |
||||
|
|
||||
|
var entities = query.Where(expression); |
||||
|
entities = GetSortingQueryable(entities, sorting); |
||||
|
var str = entities.ToQueryString(); |
||||
|
|
||||
|
Console.WriteLine("---------查询开始---------"); |
||||
|
Console.WriteLine(); |
||||
|
Console.WriteLine(str); |
||||
|
Console.WriteLine(); |
||||
|
Console.WriteLine("---------查询结束---------"); |
||||
|
|
||||
|
var result = await entities.PageBy(skipCount, maxResultCount).ToListAsync(cancellationToken) |
||||
|
.ConfigureAwait(false); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
private IQueryable<TEntity> GetSortingQueryable(IQueryable<TEntity> entities, string sorting) |
||||
|
{ |
||||
|
if (string.IsNullOrEmpty(sorting)) |
||||
|
{ |
||||
|
entities = entities.OrderBy("Id"); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
var sortParams = sorting?.Split(' '); |
||||
|
var sortName = sortParams[0]; |
||||
|
var ascOrDesc = string.Empty; |
||||
|
if (sortParams.Length > 1) |
||||
|
{ |
||||
|
var sortDirection = sortParams[1]; |
||||
|
if (sortDirection.Equals("DESC", StringComparison.OrdinalIgnoreCase)) |
||||
|
{ |
||||
|
ascOrDesc = " DESC "; |
||||
|
} |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
ascOrDesc = " DESC "; |
||||
|
} |
||||
|
|
||||
|
entities = entities.OrderBy(sortName + ascOrDesc); |
||||
|
} |
||||
|
|
||||
|
return entities; |
||||
|
} |
||||
|
|
||||
|
#endregion
|
||||
|
} |
@ -1,27 +1,27 @@ |
|||||
{ |
{ |
||||
"ConnectionStrings": { |
"ConnectionStrings": { |
||||
"Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=Winin;Trusted_Connection=True;TrustServerCertificate=True" |
"Default": "Server=.;Database=Faster.Zheng.Winin;uid=sa;pwd=sasa;timeout=6000;Encrypt=False" |
||||
}, |
}, |
||||
"OpenIddict": { |
"OpenIddict": { |
||||
"Applications": { |
"Applications": { |
||||
"Winin_Web": { |
"Winin_Web": { |
||||
"ClientId": "Winin_Web", |
"ClientId": "Winin_Web", |
||||
"ClientSecret": "1q2w3e*", |
"ClientSecret": "1q2w3e*", |
||||
"RootUrl": "https://localhost:44392" |
"RootUrl": "https://localhost:44392" |
||||
}, |
}, |
||||
"Winin_App": { |
"Winin_App": { |
||||
"ClientId": "Winin_App", |
"ClientId": "Winin_App", |
||||
"RootUrl": "http://localhost:4200" |
"RootUrl": "http://localhost:4200" |
||||
}, |
}, |
||||
"Winin_BlazorServerTiered": { |
"Winin_BlazorServerTiered": { |
||||
"ClientId": "Winin_BlazorServerTiered", |
"ClientId": "Winin_BlazorServerTiered", |
||||
"ClientSecret": "1q2w3e*", |
"ClientSecret": "1q2w3e*", |
||||
"RootUrl": "https://localhost:44367" |
"RootUrl": "https://localhost:44367" |
||||
}, |
}, |
||||
"Winin_Swagger": { |
"Winin_Swagger": { |
||||
"ClientId": "Winin_Swagger", |
"ClientId": "Winin_Swagger", |
||||
"RootUrl": "https://localhost:44380" |
"RootUrl": "https://localhost:44380" |
||||
} |
} |
||||
|
} |
||||
} |
} |
||||
} |
|
||||
} |
} |
@ -1,11 +1,11 @@ |
|||||
{ |
{ |
||||
"App": { |
"App": { |
||||
"SelfUrl": "https://localhost:44392" |
"SelfUrl": "https://localhost:44392" |
||||
}, |
}, |
||||
"ConnectionStrings": { |
"ConnectionStrings": { |
||||
"Default": "Server=(LocalDb)\\MSSQLLocalDB;Database=Winin;Trusted_Connection=True;TrustServerCertificate=True" |
"Default": "Server=.;Database=Faster.Zheng.Winin;uid=sa;pwd=sasa;timeout=6000;Encrypt=False" |
||||
}, |
}, |
||||
"StringEncryption": { |
"StringEncryption": { |
||||
"DefaultPassPhrase": "Aj66rJI3krHbVhS6" |
"DefaultPassPhrase": "Aj66rJI3krHbVhS6" |
||||
} |
} |
||||
} |
} |
||||
|
Loading…
Reference in new issue