track/src/TrackCenter.Repository/CollectionExtensions.cs
2025-08-04 17:46:29 +08:00

120 lines
3.5 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.

using System.Collections.Concurrent;
using System.Linq.Expressions;
using Nest;
using TrackCenter.Domain.SeedWork;
namespace TrackCenter.Repository;
public static class ListWrapperFactory
{
public static ListWrapper<TInput, Func<QueryContainerDescriptor<TIndex>, QueryContainer>> CreateListWrapper<TIndex, TInput>(TInput input)
where TIndex : IdBaseIndex
{
return new ListWrapper<TInput, Func<QueryContainerDescriptor<TIndex>, QueryContainer>>(new List<Func<QueryContainerDescriptor<TIndex>, QueryContainer>>(), input);
}
}
public class ListWrapper<TInput, TItem> : List<TItem>
{
public TInput Input { get; set; }
public ListWrapper(List<TItem> list, TInput input)
{
AddRange(list);;
Input = input;
}
public void AddIf(Predicate<TInput> predicate,TItem item)
{
if(predicate(Input))
Add(item);
}
}
public static class CollectionExtensions
{
private static readonly ConcurrentDictionary<Type, object?> DefaultValueCache = new();
public static void AddNotEmpty<TInput, TItem>(this ICollection<TItem> list, TInput input, TItem item)
{
if (input is null) return;
var t = typeof(TInput);
if (t == typeof(string))
{
if (!string.IsNullOrWhiteSpace(input as string))
list.Add(item);
return;
}
// 如果是Nullable类型,则获取其UnderlyingType
if (t.Name.StartsWith("Nullable"))
{
t = Nullable.GetUnderlyingType(t)!;
// 判断是否为数值类型
if (t.IsNumericType())
{
// 动态转换为数值比较
dynamic val = Convert.ChangeType(input, t);
dynamic defaultVal = Activator.CreateInstance(t);
// 当值为0时视为默认值
if (val != defaultVal)
{
list.Add(item);
}
}
return;
}
// 获取类型对应的默认值(带缓存)
var defaultValue = (TInput)DefaultValueCache.GetOrAdd(t, _ => default(TInput))!;
// 使用 EqualityComparer 避免装箱拆箱
if (!EqualityComparer<TInput>.Default.Equals(input, defaultValue))
{
list.Add(item);
}
}
public static void AddNotEmpty<TInput, TItem>(this ICollection<TItem> list, TInput input, Func<TInput, TItem> factory)
{
AddNotEmpty(list, input, factory(input));
}
public static void AddIf<TInput, TItem>(this ICollection<TItem> list, TInput input, Func<TInput, bool> predicate, TItem item)
{
if (predicate(input))
list.Add(item);
}
public static void AddIf<TInput, TItem>(this ICollection<TItem> list, TInput input, Func<TInput, bool> predicate, Func<TInput, TItem> factory)
{
if (predicate(input))
list.Add(factory(input));
}
private static bool IsNumericType(this Type? type)
{
if (type == null) return false;
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
};
}
}