using System.Collections.Concurrent; using System.Linq.Expressions; using Nest; using TrackCenter.Domain.SeedWork; namespace TrackCenter.Repository; public static class ListWrapperFactory { public static ListWrapper, QueryContainer>> CreateListWrapper(TInput input) where TIndex : IdBaseIndex { return new ListWrapper, QueryContainer>>(new List, QueryContainer>>(), input); } } public class ListWrapper : List { public TInput Input { get; set; } public ListWrapper(List list, TInput input) { AddRange(list);; Input = input; } public void AddIf(Predicate predicate,TItem item) { if(predicate(Input)) Add(item); } } public static class CollectionExtensions { private static readonly ConcurrentDictionary DefaultValueCache = new(); public static void AddNotEmpty(this ICollection 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.Default.Equals(input, defaultValue)) { list.Add(item); } } public static void AddNotEmpty(this ICollection list, TInput input, Func factory) { AddNotEmpty(list, input, factory(input)); } public static void AddIf(this ICollection list, TInput input, Func predicate, TItem item) { if (predicate(input)) list.Add(item); } public static void AddIf(this ICollection list, TInput input, Func predicate, Func 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 }; } }