我正在尝试为各种类创建动态过滤器。我们只会在运行时知道我们正在处理什么类型。我需要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;
}
答案 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);