如何构建一个与泛型对象进行比较的Linq表达式树

本文关键字:比较 Linq 表达式 对象 构建 何构建 一个 泛型 | 更新日期: 2023-09-27 17:48:53

我有一个IQueryable和一个类型为T的对象。

我想做IQueryable()。其中(o=>o.GetProperty(fieldName)==objectOfTypeT.GetProperty(field Name))

所以。。。

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不是一个有效的函数。我需要一些能起这个作用的东西。

我是周五下午大脑融化了,还是这是一件复杂的事情?


objectOfTypeT我可以执行以下操作。。。

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

这很完美,现在我只需要第二部分:

return SomeIQueryable()。其中(o=>o.GetProperty(fieldName)==matchValue);

如何构建一个与泛型对象进行比较的Linq表达式树

如此:

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

我已经开始了一个博客,它将涵盖许多表达主题,在这里。

如果遇到任何问题,另一种选择是先从objectOfTypeT中提取值(使用反射),然后在Expression.Constant中使用该值,但我怀疑"照原样"会很好。

从我目前所看到的情况来看,它一定是。。。

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

虽然我可以编译它,但它并没有完全按照要求的方式执行。

关于:

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

这是一种在不使用动态查询的情况下通过字符串获取属性值的方法。不利的一面是所有值都将被装箱/取消装箱。