2

I have the following snippet that I currently use to run a .Contains() with a list of Ids passed as a comma separated list from users. This code works perfectly and the data is filtered exactly as I want it to be:

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

I want to be able to use this same idea, except with ANY property of the u object using reflection. I had a version of this working at some point, but cannot for the life of me figure out what has changed or why it stopped working. Here is the version I have that I cannot get working again:

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

private static bool ListContainsProperty<U>(U u, ICollection<string> list, string property)
{
    string[] split = property.Split(new[] {"."}, StringSplitOptions.RemoveEmptyEntries);
    object value = split.Aggregate<string, object>(u, (current, prop) => current.GetType().GetProperty(prop).GetValue(current, null));

    return list.Contains(value.ToString());
}

As I said I once had SOME version of this working, but cannot figure out what has changed. Is there something blatantly obvious that I am missing that would help me get this functional again?

Edit: As far as I can tell the ListContainsProperty method is never actually running. Adding a "throw new Exception()" does nothing. I just get the full unfiltered list back.

4

1 回答 1

0

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

例如在您的代码中

Expression<Func<U, bool>> contains = u => ListContainsProperty(u, splitValues, property);

是数据而不是函数。为了使用它,您需要编译它。

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

“编译”变量将调用“ListContainsProperty”方法。

于 2013-02-21T07:32:38.377 回答