如何扩展类属性上的文本搜索以包括数字文本比较

本文关键字:搜索 文本 包括 文本比较 数字 属性 何扩展 扩展 | 更新日期: 2023-09-27 17:57:00

我有以下功能,可以在类上搜索基于字符串的属性以查找文本匹配项,我想将其扩展为包括数字属性。我只想进行文本比较,而不是匹配确切的数字。

关于如何最好地缓存变量属性的一些建议也会很方便。

public bool Match<T>(T item, string searchTerm)
{
    //You should cache the results of properties here for max perf.
    IEnumerable<Func<T, string>> properties = GetPropertyFunctions<T>();
    bool match = properties.Select(prop => prop(item)).Any(value => value != null && value.Contains(searchTerm));
    return match;
}
public IEnumerable<Func<T, string>> GetPropertyFunctions<T>()
{
    var propertyInfos = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty)
        .Where(p => p.PropertyType == typeof(string)).ToList();
    var properties = propertyInfos.Select(GetPropertyFunc<T>);
    return properties;
}
public Func<T, string> GetPropertyFunc<T>(PropertyInfo propInfo)
{
    ParameterExpression x = System.Linq.Expressions.Expression.Parameter(typeof(T), "x");
    Expression<Func<T, string>> expression = System.Linq.Expressions.Expression.Lambda<Func<T, string>>(System.Linq.Expressions.Expression.Property(x, propInfo), x);
    Func<T, string> propertyAccessor = expression.Compile();
    return propertyAccessor;
}

如何扩展类属性上的文本搜索以包括数字文本比较

public IEnumerable<Func<T, string>> GetPropertyFunctions<T>()
{
    var stringProperties = GetStringPropertyFunctions<T>();
    var decimalProperties = GetDecimalPropertyFunctions<T>();
    return stringProperties.Concat(decimalProperties);
}
public IEnumerable<Func<T, string>> GetStringPropertyFunctions<T>()
{
    var propertyInfos = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty)
        .Where(p => p.PropertyType == typeof(string)).ToList();
    var properties = propertyInfos.Select(GetStringPropertyFunc<T>);
    return properties;
}
public Func<T, string> GetStringPropertyFunc<T>(PropertyInfo propInfo)
{
    ParameterExpression x = System.Linq.Expressions.Expression.Parameter(typeof(T), "x");
    Expression<Func<T, string>> expression = System.Linq.Expressions.Expression.Lambda<Func<T, string>>(System.Linq.Expressions.Expression.Property(x, propInfo), x);
    Func<T, string> propertyAccessor = expression.Compile();
    return propertyAccessor;
}

public IEnumerable<Func<T, string>> GetDecimalPropertyFunctions<T>()
{
    var propertyInfos = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty)
        .Where(p => p.PropertyType == typeof(decimal)).ToList();
    var properties = propertyInfos.Select(GetDecimalPropertyFunc<T>);
    return properties;
}
public Func<T, string> GetDecimalPropertyFunc<T>(PropertyInfo propInfo)
{
    ParameterExpression x = System.Linq.Expressions.Expression.Parameter(typeof(T), "x");
    Expression<Func<T, decimal>> expression = System.Linq.Expressions.Expression.Lambda<Func<T, decimal>>(System.Linq.Expressions.Expression.Property(x, propInfo), x);
    Func<T, decimal> propertyAccessor = expression.Compile();
    return (T item) => propertyAccessor(item).ToString();
}