145 lines
4.2 KiB
C#
145 lines
4.2 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace Admin.NET.Core.Utils;
|
||
// 聚合配置增强版(独立类)
|
||
public class AggregationBuilder
|
||
{
|
||
private readonly List<AggregationConfig> _configs;
|
||
private readonly Type _entityType;
|
||
private readonly Type _outputType;
|
||
|
||
public List<string> SelectParts { get; } = new();
|
||
public List<string> HavingConditions { get; } = new();
|
||
|
||
public AggregationBuilder(
|
||
IEnumerable<AggregationConfig> configs,
|
||
Type entityType,
|
||
Type outputType)
|
||
{
|
||
_configs = configs.ToList();
|
||
_entityType = entityType;
|
||
_outputType = outputType;
|
||
Build();
|
||
}
|
||
|
||
private void Build()
|
||
{
|
||
foreach (var config in _configs.Where(IsValidConfig))
|
||
{
|
||
// 处理SELECT部分
|
||
var expression = string.IsNullOrEmpty(config.CustomExpression)
|
||
? $"{config.Function.ToString().ToUpper()}({config.Field})"
|
||
: config.CustomExpression;
|
||
|
||
SelectParts.Add($"{expression} AS {config.Alias}");
|
||
|
||
// 处理HAVING条件
|
||
if (!string.IsNullOrEmpty(config.HavingCondition))
|
||
{
|
||
HavingConditions.Add($"{expression} {config.HavingCondition}");
|
||
}
|
||
}
|
||
}
|
||
|
||
private bool IsValidConfig(AggregationConfig config)
|
||
{
|
||
// 字段基础验证
|
||
if (!string.IsNullOrEmpty(config.Field) &&
|
||
_entityType.GetProperty(config.Field) == null)
|
||
return false;
|
||
|
||
// 输出属性验证
|
||
return _outputType.GetProperty(config.Alias) != null;
|
||
}
|
||
/// <summary>
|
||
/// 验证聚合配置有效性
|
||
/// </summary>
|
||
private bool ValidateAggregation(AggregationConfig config, Type entityType, Type outputType)
|
||
{
|
||
// 验证实体字段存在性
|
||
var entityProp = entityType.GetProperty(config.Field);
|
||
if (entityProp == null) return false;
|
||
|
||
// 验证输出字段存在性
|
||
var outputProp = outputType.GetProperty(config.Alias);
|
||
if (outputProp == null) return false;
|
||
|
||
// 验证类型兼容性
|
||
return config.Function switch
|
||
{
|
||
AggregateFunction.Count => outputProp.PropertyType == typeof(int),
|
||
_ => outputProp.PropertyType == entityProp.PropertyType ||
|
||
IsNumericType(outputProp.PropertyType)
|
||
};
|
||
}
|
||
|
||
private static bool IsNumericType(Type type)
|
||
{
|
||
return Type.GetTypeCode(type) switch
|
||
{
|
||
TypeCode.Byte or TypeCode.SByte or TypeCode.UInt16
|
||
or TypeCode.UInt32 or TypeCode.UInt64 or TypeCode.Int16
|
||
or TypeCode.Int32 or TypeCode.Int64 or TypeCode.Decimal
|
||
or TypeCode.Double or TypeCode.Single => true,
|
||
_ => false
|
||
};
|
||
}
|
||
/// <summary>
|
||
/// 验证字段有效性
|
||
/// </summary>
|
||
public static List<string> ValidateFields(string[] fields, Type targetType)
|
||
{
|
||
if (fields == null || fields.Length == 0) return new List<string>();
|
||
|
||
return fields
|
||
.Where(f => !string.IsNullOrWhiteSpace(f))
|
||
.Select(f => f.Trim())
|
||
// .Where(f => targetType.GetProperty(
|
||
// targetType == typeof(UsagetokenOutput) ?
|
||
// $"{f}Sum" : f) != null)
|
||
.ToList();
|
||
}
|
||
}
|
||
|
||
// 增强版聚合配置类
|
||
public class AggregationConfig
|
||
{
|
||
/// <summary>
|
||
/// 数据库字段名(与CustomExpression二选一)
|
||
/// </summary>
|
||
public string Field { get; set; }
|
||
|
||
/// <summary>
|
||
/// 自定义聚合表达式(优先级高于Field+Function)
|
||
/// </summary>
|
||
public string CustomExpression { get; set; }
|
||
|
||
/// <summary>
|
||
/// 聚合函数类型(使用CustomExpression时可不填)
|
||
/// </summary>
|
||
public AggregateFunction Function { get; set; } = AggregateFunction.Sum;
|
||
|
||
/// <summary>
|
||
/// 输出字段别名(必须与DTO属性名一致)
|
||
/// </summary>
|
||
public required string Alias { get; set; }
|
||
|
||
/// <summary>
|
||
/// HAVING条件表达式(如"> 100")
|
||
/// </summary>
|
||
public string HavingCondition { get; set; }
|
||
}
|
||
public enum AggregateFunction
|
||
{
|
||
Sum,
|
||
Avg,
|
||
Count,
|
||
Max,
|
||
Min,
|
||
// 可扩展其他函数
|
||
}
|