Question

I have an IQueryable and an object of type T.

I want to do IQueryable().Where(o => o.GetProperty(fieldName) == objectOfTypeT.GetProperty(fieldName))

so ...

public IQueryable<T> DoWork<T>(string fieldName)
        where T : EntityObject
{
   ...
   T objectOfTypeT = ...;
   ....
   return SomeIQueryable<T>().Where(o => o.GetProperty(fieldName) == objectOfTypeT.GetProperty(fieldName));
}

Fyi, GetProperty isn't a valid function. I need something which performs this function.

Am I having a Friday afternoon brain melt or is this a complex thing to do?


objectOfTypeT I can do the following ...

var matchToValue = Expression.Lambda(ParameterExpression
.Property(ParameterExpression.Constant(item), "CustomerKey"))
.Compile().DynamicInvoke();

Which works perfectly,now I just need the second part:

return SomeIQueryable().Where(o => o.GetProperty(fieldName) == matchValue);

Was it helpful?

Solution

Like so:

    var param = Expression.Parameter(typeof(T), "o");
    var fixedItem = Expression.Constant(objectOfTypeT, typeof(T));
    var body = Expression.Equal(
        Expression.PropertyOrField(param, fieldName),
        Expression.PropertyOrField(fixedItem, fieldName));
    var lambda = Expression.Lambda<Func<T,bool>>(body,param);
    return source.Where(lambda);

I have started a blog which will cover a number of expression topics, here.

If you get any problems, another option is to extract the value from objectOfTypeT first (using reflection) and then use that value in the Expression.Constant, but I suspect it'll be fine "as is".

OTHER TIPS

From what I can see so far it's going to have to be something like ...

IQueryable<T>().Where(t => 
MemberExpression.Property(MemberExpression.Constant(t), fieldName) == 
ParameterExpression.Property(ParameterExpression.Constant(item), fieldName));

While I can get this to compile it's not quite executing the way it is required.

What about:

    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }

    }

    public Func<T, TRes> GetPropertyFunc<T, TRes>(string propertyName)
    {
        // get the propertyinfo of that property.
        PropertyInfo propInfo = typeof(T).GetProperty(propertyName);

        // reference the propertyinfo to get the value directly.
        return (obj) => { return (TRes)propInfo.GetValue(obj, null); };
    }

    public void Run()
    {
        List<Person> personList = new List<Person>();

        // fill with some data
        personList.Add(new Person { Name = "John", Age = 45 });
        personList.Add(new Person { Name = "Michael", Age = 31 });
        personList.Add(new Person { Name = "Rose", Age = 63 });

        // create a lookup functions  (should be executed ones)
        Func<Person, string> GetNameValue = GetPropertyFunc<Person, string>("Name");
        Func<Person, int> GetAgeValue = GetPropertyFunc<Person, int>("Age");


        // filter the list on name
        IEnumerable<Person> filteredOnName = personList.Where(item => GetNameValue(item) == "Michael");
        // filter the list on age > 35
        IEnumerable<Person> filteredOnAge = personList.Where(item => GetAgeValue(item) > 35);
    }

This is a way to get values of a properties by string without using of dynamic queries. The downside is al values will be boxed/unboxed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top