2008-10-24 39 views
3

我有一個IQueryable和類型T的對象如何構建與通用對象進行比較的Linq表達式樹?

我想要做的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(); 

這完美的作品,現在我只是需要第二部分:

回報SomeIQueryable()式(O =>o.GetProperty(fieldName) == matchValue);

回答

4

像這樣:

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

我已經開始了一個博客,這將涉及一系列的表達主題,here

如果您遇到任何問題,另一種方法是首先從objectOfTypeT中提取值(使用反射),然後在Expression.Constant中使用該值,但我懷疑它會「按原樣」處理。

+0

完美。正是我需要的。 現在要弄清楚到底發生了什麼:) – JTew 2008-10-24 04:03:08

0

從我目前可以看到它的將不得不是這樣的......

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

雖然我能得到這個編譯它並不完全執行它需要的方式。

+0

關閉;你需要建立一個LambdaExpression - 看我的文章。 – 2008-10-24 04:02:01

0

什麼:

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

這是一種通過字符串,不使用動態查詢來獲得屬性的值。缺點是阿爾值將被裝箱/取消裝箱。

相關問題