动态列表<t> </t>的位置

时间:2009-08-07 19:30:35

标签: 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;
}

3 个答案:

答案 0 :(得分:12)

基本上你需要构建一个表达式树。幸运的是,使用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);
        }
    }
}

答案 1 :(得分:0)

而不是字符串ColumnName,你不能传递该列的选择器(我意识到这并不总是可行,但以防它是......)?你可以使用,然后。

顺便说一句,代码太复杂了。这应该有效:

public static List<T> Filter<T>(
    this List<T> Source, Func<T, string> selector, string CompValue)
{
    return Source.Where(a => selector(a) == CompValue).ToList();
}

然后您可以按如下方式调用代码:

var result = myList.Filter(x => x.ColumnName, "foo");

答案 2 :(得分:0)

你在寻找这样的东西:http://naspinski.net/post/Writing-Dynamic-Linq-Queries-in-Linq-to-Entities.aspx  否则,您必须分别处理每个案例,如下所示:

if (columnName == "blah")
  matches = matches.Where(i => i.Blah == Value);
if (columnName == "name")
  matches = matches.Where(i => i.Name == Value);