2016-12-21 18 views
2

我在運行時爲實體框架構建表達式,並且除了從子ICollection中選擇一個屬性外,我已經解決了所有問題。Expression.Call類型System.Collections.Generic.ICollection上沒有方法'Select'

很難發佈我的整個框架,但這裏是我所嘗試過的。

var param = Expression.Parameter(typeof(TEntity), "w"); 
Expression.Property(entity, propertyName); 

w.Roles

var param = Expression.Parameter(typeof(TChild), "z"); 
Expression.Property(entity, propertyName); 

z.ApplicationRole.Name

此行引發錯誤。

Expression.Call(property, "Select", null,(MemberExpression)innerProperty); 

這是錯誤。

無方法 '選擇' 存在於 型「System.Collections.Generic.ICollection`1 [ApplicationUserRole]

這就是我試圖動態地產生。

await context.Users.Where(c => c.Roles 
           .Select(x => x.ApplicationRole.Name) 
           .Contains("admin")) 
        .ToListAsync(); 

我會很感激任何人可以幫助。

+3

選擇LAMDA表達式在System.Linq的命名空間的擴展方法,所以你不能直接調用它與反思的對象。 請參閱:http://stackoverflow.com/questions/1452261/how-do-i-invoke-an-extension-method-using-reflection –

回答

3

正如在評論中已經提到的,Select不是IColletion的一種方法,它是一種擴展方法,您不能直接從ICollection調用Select

您可以創建SelectMethodInfo這樣:

var selM = typeof(Enumerable) 
     .GetMethods() 
     .Where(x => x.Name == "Select") 
     .First().MakeGenericMethod(typeof(TEntity), typeof(string)); 

和你的表達,你可以爲創建:

var selExpression = Expression.Call(null, selM, param , lambda); 

重要的是,中Expression.Call是第一個參數爲空,Select是一個靜態擴展方法,它沒有任何實例被調用。

lambda票數是從你的財產表達

var prop= Expression.Property(entity, propertyName); 
var lambda = Expression.Lambda(prop, param); 
+0

我困在lamda上。我不知道什麼是參數。我已經嘗試了很多東西,包括這個Expression.Lambda(property,(MemberExpression)innerProperty); – MIKE

+0

明白了。非常感謝! var lambda = Expression.Lambda((MemberExpression)innerProperty,innerParam); – MIKE

相關問題