private static readonly MethodInfo MethodEnumerableContains = typeof(Enumerable).GetMethods().First(a => a.Name == "Contains");
/// <summary>
/// 字符串集合转换器字典
/// </summary>
private static readonly Dictionary<Type, Func<string[], object>> TypeConverters = new()
{
{typeof(string), values => values},
{typeof(ushort), values => values.Select(ushort.Parse) },
{typeof(ushort?), values => values.Select(s => ushort.TryParse(s, out var intValue) ? (ushort?)intValue : null) },
{typeof(short), values => values.Select(short.Parse) },
{typeof(short?), values => values.Select(s => short.TryParse(s, out var intValue) ? (short?)intValue : null) },
{typeof(int), values => values.Select(int.Parse) },
{typeof(int?), values => values.Select(s => int.TryParse(s, out var intValue) ? (int?)intValue : null) },
{typeof(long), values => values.Select(long.Parse) },
{typeof(long?), values => values.Select(s => long.TryParse(s, out var intValue) ? (long?)intValue : null) },
{typeof(decimal), values => values.Select(decimal.Parse) },
{typeof(decimal?), values => values.Select(s => decimal.TryParse(s, out var intValue) ? (decimal?)intValue : null) },
{typeof(double), values => values.Select(double.Parse) },
{typeof(double?), values => values.Select(s => double.TryParse(s, out var intValue) ? (double?)intValue : null) },
{typeof(float), values => values.Select(float.Parse) },
{typeof(float?), values => values.Select(s => float.TryParse(s, out var intValue) ? (float?)intValue : null) },
{typeof(bool), values => values.Select(bool.Parse) },
{typeof(bool?), values => values.Select(s => bool.TryParse(s, out var intValue) ? (bool?)intValue : null) },
{typeof(Guid), values => values.Select(Guid.Parse) },
{typeof(Guid?), values => values.Select(s => Guid.TryParse(s, out var intValue) ? (Guid?)intValue : null) },
{typeof(DateTime), values => values.Select(DateTime.Parse) },
{typeof(DateTime?), values => values.Select(s => DateTime.TryParse(s, out var intValue) ? (DateTime?)intValue : null) },
};
/// <summary>
/// 创建In解析表达式
/// </summary>
/// <param name="left"></param>
/// <param name="condition"></param>
/// <returns></returns>
private static Expression CreateExpressionIn(Expression left, FilterCondition condition)
{
// 值数组
var values = condition.Value.Split(',');
// 判断是否包含方法
var method = MethodEnumerableContains.MakeGenericMethod(left.Type);
// 枚举类型判断
if (left.Type.BaseType == typeof(Enum))
{
var fiValueAnyArrayType = left.Type.MakeArrayType();
var enumValues = values.Select(v => Enum.Parse(left.Type, v));
var constantEnumCollection = Expression.Constant(enumValues, fiValueAnyArrayType);
return Expression.Call(method, constantEnumCollection, left);
}
// 值类型判断
if (!TypeConverters.TryGetValue(left.Type, out var converter))
throw new NotSupportedException($"“ParseIn”不支持此类型{left.Type.Name}的数据");
var objectValues = converter(values);
var constantCollection = Expression.Constant(objectValues);
return Expression.Call(method, constantCollection, left);
};
由于Enum.Parse返回为object类型,所以Expression.Constant一直报错对象不匹配
Select识别不到动态类型,返回的总是ojbect[],还是用这个吧...
var enumArray = Array.CreateInstance(left.Type, values.Length);
for (int i = 0; i < values.Length; i++)
{
enumArray.SetValue(Enum.Parse(left.Type, values[i]), i);
}
确实没想到这个方法,0.0