如何扩展此LINQ列表.Contains以使用反射处理任何属性?

如何扩展此LINQ列表.Contains以使用反射处理任何属性?,linq,nhibernate,reflection,dynamic-linq,Linq,Nhibernate,Reflection,Dynamic Linq,我当前使用以下代码段运行.Contains,其中包含以逗号分隔的列表形式从用户处传递的ID列表。此代码工作正常,数据过滤完全符合我的要求: // Handle id in() statements explicitly, dynamic expression can't parse them var idIn = new Regex("id in ?(.*)", RegexOptions.IgnoreCase); if (idIn.IsMatch(predicate)) { Match

我当前使用以下代码段运行.Contains,其中包含以逗号分隔的列表形式从用户处传递的ID列表。此代码工作正常,数据过滤完全符合我的要求:

// Handle id in() statements explicitly, dynamic expression can't parse them
var idIn = new Regex("id in ?(.*)", RegexOptions.IgnoreCase);
if (idIn.IsMatch(predicate))
{
    Match list = new Regex(@"in ?\((.*)\)", RegexOptions.IgnoreCase).Match(predicate);
    string ins = list.Groups[1].ToString();

    // Split ins and store as List<>
    List<int> splitValues = ins.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Select(i => Convert.ToInt32(i)).ToList();

    return source.Where(u => splitValues.Contains(u.Id));
}
我希望能够使用相同的想法,除了使用反射的u对象的任何属性。我有一个版本的这个工作在某个点上,但不能为我的生活,找出什么改变了,为什么它停止工作。以下是我无法再次工作的版本:

Match splitIn = new Regex(@"([a-zA-Z0-9\.]*) IN ?\((.*)\)", RegexOptions.IgnoreCase).Match(predicate);
string property = splitIn.Groups[1].ToString();
string ins = splitIn.Groups[2].ToString().Trim(new[] {'\'', '"'}); // Trim off separator quotes

List<string> splitValues = ins.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).ToList();
for (int i = 0; i < splitValues.Count; i++)
{
    splitValues[i] = splitValues[i].Trim(new[] {'\'', '"'});
}

Expression<Func<U, bool>> contains = u => ListContainsProperty(u, splitValues, property);
return source.Where(contains);
正如我所说的,我曾经有过这个版本的作品,但我不知道发生了什么变化。是否有一些明显的东西,我错过了,这将帮助我得到这个功能再次


编辑:据我所知,ListContainesProperty方法从未实际运行过。添加一个抛出新异常没有任何作用。我只是得到完整的未过滤列表。

我认为根本的问题是使用表达式 您需要编译一个表达式

例如,在您的代码中

Expression<Func<U, bool>> contains = u => ListContainsProperty(u, splitValues, property);
是数据而不是函数。为了使用它,您需要编译它

Func<U, bool> compiled = contains.Compile();

编译后的变量将调用ListContainsProperty方法。

我认为潜在的问题是使用表达式 您需要编译一个表达式

例如,在您的代码中

Expression<Func<U, bool>> contains = u => ListContainsProperty(u, splitValues, property);
是数据而不是函数。为了使用它,您需要编译它

Func<U, bool> compiled = contains.Compile();

编译后的变量将调用ListContainsProperty方法。

您的代码本身不会运行ListContainsProperty。只有在您迭代source.Wherecontains时,它才会运行。即使存在最终的.ToList,并且数据被转储到数据网格中,它仍然不会运行。因此,即使只是执行foreach并打印每个项目,ListContainsProperty仍然不会被调用。您的代码本身也不会运行ListContainsProperty。它只会在您迭代source.Wherecontains.时运行。即使存在最终的.ToList,并且数据被转储到datagrid中,它仍然不会运行。因此,即使只是执行foreach并打印每个项,ListContainsProperty仍然不会被调用