linq 是否可以修改此函数以处理多个属性比较?

inkz8wg9  于 2023-09-28  发布在  其他
关注(0)|答案(2)|浏览(111)

作为参考,这里是最初的问题(请记住,Filter()函数源于这篇文章):动态Where for List
原始帖子的功能清晰:

public static List<T> Filter<T>
        (this List<T> source, string columnName, 
         string compValue)
    {
        ParameterExpression parameter = Expression.Parameter(typeof(T), "x");
        Expression property = Expression.Property(parameter, columnName);
        Expression constant = Expression.Constant(compValue);
        Expression equality = Expression.Equal(property, constant);
        Expression<Func<T, bool>> predicate =
            Expression.Lambda<Func<T, bool>>(equality, parameter);

        Func<T, bool> compiled = predicate.Compile();
        return source.Where(compiled).ToList();
    }

它允许您这样做:

var people = new[] {
            new { FirstName = "John", LastName = "Smith" },
            new { FirstName = "John", LastName = "Smith" },
            new { FirstName = "John", LastName = "Noakes" },
            new { FirstName = "Linda", LastName = "Smith" },
            new { FirstName = "Richard", LastName = "Smith" },
            new { FirstName = "Richard", LastName = "Littlejohn" },
        }.ToList();

var filtered = people.Filter("LastName", "Smith");

但如果你有多个属性要匹配呢?例如,如果我想过滤所有名为John且姓为Smith的人
我相信有一种更优雅的方式来编写这个代码:

var filtered = people.Filter(new [] {Column="FirstName", Value = "John"}, {Column="LastName", Value="Smith"});

同样好奇的是,这是否可以很容易地适应处理任何类型的属性(即对象,而不是像示例那样总是字符串)。我还没有与这些表达式树工作了很多,我很感激你能提供任何帮助。

6kkfgxo0

6kkfgxo01#

您可以使用AndAlso扩展合并多个表达式。然后将过滤器方法更改为:

public static List<T> Filter<T>(this List<T> source, params (string columnName, string compValue)[] filters)
{
    Expression<Func<T, bool>> exp = null;
    
    foreach (var filter in filters)
    {
        ParameterExpression parameter = Expression.Parameter(typeof(T), "x");
        Expression property = Expression.Property(parameter, filter.columnName);
        Expression constant = Expression.Constant(filter.compValue);
        Expression equality = Expression.Equal(property, constant);
        Expression<Func<T, bool>> predicate = Expression.Lambda<Func<T, bool>>(equality, parameter);
        
        exp = exp is null ? predicate : exp.AndAlso(predicate);
    }

    Func<T, bool> compiled = exp.Compile();
    return source.Where(compiled).ToList();
}

然后这样称呼它:

var results = people.Filter(("FirstName", "John"), ("LastName", "Smith"));

这篇文章写得很快,所以你可能不喜欢使用元组列表。

jhkqcmku

jhkqcmku2#

var people = new[] {
        new { FirstName = "John", LastName = "Smith" },
        new { FirstName = "John", LastName = "Smith" },
        new { FirstName = "John", LastName = "Noakes" },
        new { FirstName = "Linda", LastName = "Smith" },
        new { FirstName = "Richard", LastName = "Smith" },
        new { FirstName = "Richard", LastName = "Littlejohn" },
    }.ToList();
   var TestData=people.Where(o=>o.FirstName=="John" && o.LastName == "Smith" ).ToList();

您在“TestData”上获得结果列表

相关问题