【问题标题】:Using Dynamic Linq To Filter A Collection使用动态 Linq 过滤集合
【发布时间】:2015-10-06 00:09:23
【问题描述】:

我想使用动态 linq 来匹配对象的属性。在我的示例中,我有一个 Turtle 类,它有两个属性。将来,我可能会给它更多的属性。我有一个 FilterTurtles() 方法,它绑定到 Turtle 类的属性并且不可扩展。我想使用动态 linq 使其可扩展。例如,假设我想按名称“Gilly”和颜色“Brown”进行过滤,可能还有一个名为“Breed”的未来属性。如何在 FilterTurtlesWithLinq() 方法中使用动态 linq 过滤海龟集合?

public class Turtle
{
    public string Name { get; set; }
    public string Color { get; set; }
}

public class Filter
{
    public string Name { get; set ;}
    public string Value { get; set ;}
}   

public class Test
{
    private List<Turtle> Turtles { get; set;}

    public Test()
    {
        Turtles = new List<Turtle>();
        Turtles.Add(
        {
            new Turtle { Name = "Gilly", Color = "Brown" },
            new Turtle { Name = "Flow", Color = "Green" },
            new Turtle { Name = "Howard", Color = "Yellow" },
            new Turtle { Name = "Mara", Color = "Black" },
            new Turtle { Name = "Slimer", Color = "Green" },
            new Turtle { Name = "Tor", Color = "Brown" },
            new Turtle { Name = "Quartz", Color = "Yellow" },
            new Turtle { Name = "Gilly", Color = "Green" },
            new Turtle { Name = "Flow", Color = "Green" },
            new Turtle { Name = "Howard", Color = "Brown" }
        })
    }

    public IEnumerable<Turtle> FilterTurtles(string name, string color)
    {
        // This is the current code, but it's not extensible. If I add more properties
        // to the Turtle class, then I have to add more conditional statements.
        if (name != null)
        {
            return from t in Turtles
                   where t.Name == name
                   select t;
        }
        else if (color != null)
        {
            return from t in Turtles
                   where t.Color == color
                   select t;
        }
        else
        {
            return Turtles;
        }
    }

    public IEnumerable<Turtle> FilterTurtlesWithLinq(List<Filter> filters)
    {
        // I want to use dynamic linq here. For example, I want something like this:
        // "select all the turtles which match the filters"

        return null;
    }       
}

【问题讨论】:

    标签: c# asp.net linq visual-studio


    【解决方案1】:

    你不需要使用动态 Linq,一个通用的扩展方法可以让你传入任意数量的过滤器,像这样:

    public static IEnumerable<T> Filter<T>(this IEnumerable<T> input, 
        params Func<T, bool>[] filters)
    {
        var filtered = input;
    
        foreach(var filter in filters)
        {
            filtered = filtered.Where(filter);
        }
        return filtered;
    }
    

    你可以这样使用它:

    var filteredTurtles = Turtles.Filter(
        t => t.Name == "Gilly", 
        t => t.Color == "Brown");
    

    【讨论】:

    • 您的过滤器使用 And 运算符。我认为OP需要
    • @SaeedNamati 我不这么认为。 OP 说“我想按名称“Gilly”颜色“Brown”进行过滤,可能是一个名为“Breed”的未来属性。”
    • 但他的评论 select all the turtles which match the filters 在他的代码中似乎不仅仅是 AND 运算符。可能我理解错了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-26
    • 2011-04-21
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多