What is the best way to create a Linq Expression Tree that compares to a generic object?

c# entity-framework expression-trees generics linq

Question

I also have a T-type object and an IQueryable.

I want to use IQueryable (). In which(o => GetProperty(fieldName) == GetProperty(fieldName) for objectOfTypeT

so ...

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

Just so you know, GetProperty is a bad function. I need something that serves this purpose.

Is this a difficult task or am I having a brain melt on a Friday afternoon?


I'm able to accomplish the following using objectOfTypeT.

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

Which is wonderful; all I need is the second portion.

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

1
3
4/5/2009 6:13:18 AM

Accepted Answer

So as to:

    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've launched a blog called here that will discuss a variety of expression-related issues.

The value from may also be extracted if you run into issues.objectOfTypeT Initially (by reflection), utilize that value in theExpression.Constant , but I believe it will work just fine "as is".

4
10/24/2008 3:57:18 AM

Popular Answer

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

Without the use of dynamic queries, you may get the values of a property by string using this method. All values will be boxed and unboxed, which is a drawback.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow