嗨可以說我有一個屬性路徑看起來像這樣構建從一個的PropertyPath Lambda表達式
我們可以說,我有一個具有還原的文章和增值稅有一個值。 現在我想使用Linq使用屬性路徑 我怎樣才能建立一個lambda表達式時,我在字符串中有「Vat.Value」排序名單,我想下面的結果
list.Order(x => x.Vat.Value)
我不會總是知道增值稅和價值的類型,有時只有我出去的x.Name。
嗨可以說我有一個屬性路徑看起來像這樣構建從一個的PropertyPath Lambda表達式
我們可以說,我有一個具有還原的文章和增值稅有一個值。 現在我想使用Linq使用屬性路徑 我怎樣才能建立一個lambda表達式時,我在字符串中有「Vat.Value」排序名單,我想下面的結果
list.Order(x => x.Vat.Value)
我不會總是知道增值稅和價值的類型,有時只有我出去的x.Name。
有沒有你不能使用現有的LINQ動態查詢庫中的原因,哪些重載需要字符串?
http://msdn.microsoft.com/en-us/vcsharp/bb894665.aspx
它可能會做你剛纔寫了同樣的事情,但它的代碼,你不必維持並可能有一些優化。
我不確定我完全理解這個問題,但是像這樣的東西看起來像你想要的。請注意,爲了清楚起見,我可能會將lambda重構爲輔助方法。還要注意,使用這種反射可能會導致性能顯着下降,具體取決於您的收藏有多大。
[Test]
public void OrderByUsingReflection()
{
var values = new[]
{
new { Vat = new { Value = "two"}},
new { Vat = new {Value = "one"}},
};
var result = values.OrderBy(x =>
{
var vat = x.GetType().GetProperty("Vat").GetValue(x, null);
return vat.GetType().GetProperty("Value").GetValue(vat, null);
});
Assert.AreEqual(result.ToList()[0], values[1]);
Assert.AreEqual(result.ToList()[1], values[0]);
}
我用擴展方法修復了它。該方法使用的PropertyPath現在例如
var orderedArticles = articles.OrderBy("Vat.Value");
,而不是
var orderedArticles = articles.OrderBy(x => x.Vat.Value)
擴展方法:
private static Func<T, TReturnType> GetLambda<T, TReturnType>(IEnumerable<string> propertyNames)
{
var rootParameterExression = Expression.Parameter(typeof(T));
Expression expression = rootParameterExression;
foreach (var propertyName in propertyNames)
{
expression = Expression.Property(expression, propertyName);
}
return Expression.Lambda<Func<T, TReturnType>>(expression, rootParameterExression).Compile();
}
public static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> queryable, string propertyPath)
{
var propertyPathList = propertyPath.Split(Convert.ToChar("."));
Type propertyType = typeof(T);
foreach (var propertyName in propertyPathList)
{
propertyType = propertyType.GetProperty(propertyName).PropertyType;
}
if(propertyType == typeof(decimal))
{
var lambda = GetLambda<T, Decimal>(propertyPathList);
return queryable.OrderBy(lambda);
}
var lamda = GetLambda<T, object>(propertyPathList);
return queryable.OrderBy(lamda);
}
我認爲我現在發佈的那個更高效,更易於使用。 – NPehrsson 2010-11-02 20:22:59