UNIVPLMDataIntegration/Admin.NET/Admin.NET.Core/Utils/AggregationBuilder.cs
zuohuaijun c8d6d7ce1e 😎代码清理
2025-02-27 16:27:16 +08:00

149 lines
4.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core.Utils;
/// <summary>
/// 聚合配置增强版(独立类)
/// </summary>
public class AggregationBuilder
{
private readonly List<AggregationConfig> _configs;
private readonly Type _entityType;
private readonly Type _outputType;
public List<string> SelectParts { get; } = [];
public List<string> HavingConditions { get; } = [];
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 static 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<T>(string[] fields, Type targetType)
{
if (fields == null || fields.Length == 0) return [];
return fields.Where(u => !string.IsNullOrWhiteSpace(u))
.Select(u => u.Trim())
.Where(u => targetType.GetProperty(targetType == typeof(T) ? $"{u}Sum" : u) != null)
.ToList();
}
}
/// <summary>
/// 增强版聚合配置类
/// </summary>
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 string Alias { get; set; }
/// <summary>
/// HAVING条件表达式如"> 100"
/// </summary>
public string HavingCondition { get; set; }
}
/// <summary>
/// 函数枚举
/// </summary>
public enum AggregateFunction
{
Sum,
Avg,
Count,
Max,
Min,
// 可扩展其他函数
}