如何構建與通用對象進行比較的Linq表達式樹?

c# entity-framework expression-trees generics linq

我有一個IQueryable和一個類型為T的對象。

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

所以......

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()。Where(o => o.GetProperty(fieldName) == matchValue);

一般承認的答案

像這樣:

    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使用該值,但我懷疑它會“按原樣”。


熱門答案

關於什麼:

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

這是一種在不使用動態查詢的情況下通過字符串獲取屬性值的方法。缺點是al值將被裝箱/取消裝箱。



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因