动态列表<T>的位置

Joh*_* K. 6 c# linq-to-entities

我正在尝试为各种类创建动态过滤器.我们只会在运行时知道我们正在处理什么类型.我需要ColumnName作为实际列(不是字符串值).

有没有一种简单的方法将字符串转换为列?

public static List<T> Filter<T>
    (this List<T> Source, string ColumnName, 
    string TypeOfCompare, string CompValue)
{
    IQueryable<T> matches = Source.AsQueryable();

    if (ColumnName.Length > 0)
    {
        matches = (IEnumerable)matches.Where(a => ColumnName == CompValue)
    }

    List<T> ReturnList2 = new List<T>();
    ReturnList2 = matches.ToList();
    return ReturnList2;
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 13

基本上你需要构建一个表达式树.幸运的是,使用它并不是非常困难Expression.Property.您可以将其传递给Queryable.Where,或者将其编译并传递给它Enumerable.Where.(显然你需要使用类似的东西Expression.Equal ,这取决于你想要做的比较类型.)

CompValue一个实际价值?这TypeOfCompare是什么意思?

我不确定LINQ to Entities在哪里适合这个,或者......你只是真正使用LINQ to Objects,据我所见.

编辑:好的,这是一个样本.它假定你想要平等,但如果是这样,它会做你想要的.我不知道每次编译表达式树会对性能产生什么影响 - 您可能希望为任何给定的名称/值组合缓存委托:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

static class Extensions
{
    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();
    }
}

class Test
{
    static void Main()
    {
        var people = new[] {
            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();

        foreach (var person in people.Filter("LastName", "Smith"))
        {
            Console.WriteLine(person);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)