120 lines
3.5 KiB
C#
120 lines
3.5 KiB
C#
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
|
||
};
|
||
}
|
||
}
|