动态凡列表< T> [英] Dynamic Where for List<T>

查看:86
本文介绍了动态凡列表< T>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创造各种类的动态过滤器。我们只知道我们正在处理什么类型与运行。我需要的ColumnName是实际列(不是字符串值)。



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

 公共静态列表< T>过滤< T> 
(名单< T>来源,字符串的ColumnName,
串TypeOfCompare,串CompValue)
{
&IQueryable的LT; T>匹配= Source.AsQueryable();

如果(ColumnName.Length大于0)
{
匹配=(IEnumerable的)matches.Where(A =>的ColumnName == CompValue)
$} b
$ b文件清单< T> ReturnList2 =新的List< T>();
ReturnList2 = matches.ToList();
返回ReturnList2;
}


解决方案

基本上你需要建立一个表达式树。这不是非常难,幸运的是,使用 Expression.Property 。您可以传递到 Queryable.Where ,或编译它,并将它传递给 Enumerable.Where 。 (显然,你需要使用像 Expression.Equal
为好,这取决于你试图做的比较类型。)



CompValue 意思是实际值?什么是 TypeOfCompare 意思是什么?



我不知道在哪里LINQ到实体适合此项工作,要么.. 。你只使用LINQ到对象真的,据我可以看到



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

 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;使用System.Linq.Expressions
;

静态类扩展
{
公共静态列表< T>过滤< T>
(名单< T>源,串COLUMNNAME,
串compValue)
{
ParameterExpression参数= Expression.Parameter(typeof运算(T),X);
Expression属性= Expression.Property(参数,COLUMNNAME);
表达常数= Expression.Constant(co​​mpValue);
表达平等= Expression.Equal(属性不变);
表达式来; Func键< T,BOOL>>谓词=
Expression.Lambda<&Func键LT; T,BOOL>>(平等,参数);

Func键< T,BOOL>编译= predicate.Compile();
返回source.Where(编译).ToList();
}
}

类测试
{
静态无效的主要()
{
变种人=新的[] {
新{名字=约翰,姓氏=史密斯},
新{名字=约翰,姓氏=诺克斯},
新{名字=琳达姓氏=史密斯},
新{名字=理查德,姓氏=史密斯},
新{名字=理查德,姓氏=利特尔约翰},
} .ToList();

的foreach(VAR人people.Filter(姓氏,史密斯))
{
Console.WriteLine(人);
}
}
}


I'm trying to create a dynamic filter for various classes. We would only know at runtime what type we're dealing with. I need the ColumnName to be the actual column (not a string value).

Is there an easy way to convert the string into a column?

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;
}

解决方案

Basically you need to build an expression tree. It's not terribly hard, fortunately, using Expression.Property. You can either pass that to Queryable.Where, or compile it and pass it to Enumerable.Where. (Obviously you'll need to use something like Expression.Equal as well, depending on the type of comparison you're trying to make.)

Is CompValue meant to be an actual value? What's TypeOfCompare meant to be?

I'm not sure where LINQ to Entities fits into this, either... you're only using LINQ to Objects really, as far as I can see.

EDIT: Okay, here's a sample. It assumes you want equality, but it does what you want if so. I don't know what the performance impact of compiling an expression tree every time is - you may want to cache the delegate for any given name/value combination:

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

这篇关于动态凡列表&LT; T&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆