0

I currently have a LINQ expression for a property accessor that accesses a property on an object. I now need to build a LINQ expression that will evaluate a predicate to see if the result from the property accessor is contained within a list.

I've seen that in most cases this kind of thing is done using the static methods on Expression, however there is no Contains or In available as a static method on Expression, so I am unsure how to proceed.

// A data object
internal class PersonDAL
{
    public int Age ( get; set; }
}

// A business object
public class Person
{
    private PersonDAL root { get; set; }

    public static Expression<Func<PersonDAL, int>> AgeExpression
    {
        get
        {
            return (root) => (root.Age);
        }
    }
}

Now I want to be able to check if the value of AgeExpression is contained within a list of ages. Normally this would be something like writing an expression to see if the list of values contains the value that I want to check for, but I don't see how to feed the result of an expression in as the value to search for.

To clarify a little, I'm trying to figure out how to take a queryable that has all Persons and get just the Persons where an unknown expression evaluates true based on a value from another expression. In my sample case, the unknown accessor expression is looking at the Age of a Person and it needs to be able to evaluate if it is contained within another list of acceptable ages.

AJ Henderson
  • 1,120
  • 1
  • 12
  • 32
  • LINQ to Entities? LINQ to Objects? LINQ to XML? – dtb Apr 23 '13 at 15:48
  • @dtb - currently the underlying DAL is an older version of the Codesmith PLINQO templates. I've built the property accessors in the BOL objects manually which point to the DAL objects that PLINQO makes. – AJ Henderson Apr 23 '13 at 15:51
  • How would you make the query without a dynamic expression? – dtb Apr 23 '13 at 15:53
  • AgeExpression being static won't work. It needs access to the instance variable. Should it be non-static, or is there something else I'm missing? – Shlomo Apr 23 '13 at 15:56
  • @Shlomo - It's an accessor expression. It's a function that is fed a particular instance of the PersonDal and evaluates the property on that instance. – AJ Henderson Apr 23 '13 at 15:58

2 Answers2

1

I'm not sure why you're using expressions. I don't see what you gain by them. But if you modify the signature of AgeExpression to be Expression<Func<PersonDAL, int>>, you can compile it and execute it:

void Main()
{
    var pDal = new PersonDAL { Age = 3 };

    var ageFunc = Person.AgeExpression.Compile();
    var age = ageFunc(pDal);
    // age is 3
}

// Define other methods and classes here

// A data object
public class PersonDAL
{
    public int Age { get; set; }
}

// A business object
public class Person
{
    public Person(PersonDAL dal)
    {
        this.dal = dal;
    }

    private PersonDAL dal { get; set; }

    public static Expression<Func<PersonDAL, int>> AgeExpression
    {
        get
        {
            return (root) => (root.Age);
        }
    }
}
Shlomo
  • 14,102
  • 3
  • 28
  • 43
  • The underlying reason is trying to build a LINQ compatible filter framework. All that is actually going to be known at runtime is the expressions that define how to resolve a particular value and I'll then have to use that value in a filter. The compilation and execution may still be what I need though, so I'll give that a shot and see where I can get. – AJ Henderson Apr 23 '13 at 16:08
  • Oh, also, I actually did already have the Func there I just missed it when transposing it to an example. What I'm not sure is what I would pass in though for the value to pass to it when it's being accessed within my other expression. To give a more complete example, say I'm selecting a list of Person's where their Age is in the list of 10, 20 and 30. I can add the ages to a list and do a AgeList.Contains(AgeAccessorFunc(??)) but I need some way to connect my selection of Person's to the Contains and the accessor. – AJ Henderson Apr 23 '13 at 16:16
  • And I assume AgeList is some form of IQueryable? So would the query look something like this: Persons.Where(p => AgeList.Contains(p.Age))? – Shlomo Apr 23 '13 at 16:41
  • yes, something like that. I think it would actually be the Age function taking p as a parameter. Pretty sure that works for the concrete example, what I'm not sure about is how I assemble that if there are additional criteria though. I think that is probably branching out in to another question though. – AJ Henderson Apr 23 '13 at 17:31
0

This kind of problem foxed me a lot too.. remember that you can access local variables within your LINQ/lambda expressions: so a simple .where(x => x.value == AgeExpression) should point you in the right direction

Izzy
  • 1,764
  • 1
  • 17
  • 31