可以修改此函数来处理多个属性比较吗?

问题描述 投票:0回答:2

供参考,这是原始问题:DynamicWhere for List

这允许您执行此操作:

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");

但是如果您想要匹配多个属性怎么办?例如,如果我想过滤所有名字=约翰和姓氏=史密斯的人

Pseduocode 只是为了给出这个想法,我确信有一种更优雅的方式来编码:

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

也很好奇这是否可以轻松地适应处理属性的任何类型(即对象而不是像示例那样总是字符串)。我没有太多使用这些表达式树,我感谢您提供的任何帮助。

c# linq expression-trees
2个回答
2
投票

您可以使用此处的

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"));

这篇文章写得很快,因此您可能不喜欢使用元组列表。


-2
投票
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”上获得结果列表

© www.soinside.com 2019 - 2024. All rights reserved.