2017-10-18 63 views
0

我想創建一個動態的方式來返回一個排序列表的參數xy。該列表可以按降序,升序,ID,用戶名,郵件和許多其他方式排序。dotnet .net core 2 OrderBy/OrderByDescending與通用參數

我收到此參數作爲字符串。例如,sort=-username

減號表示列表遞減。排序參數是用戶名。

所以我回到user.OrderByDescending(o => o.Username).ToList();

目前有長的if-else結構我發現需要其排序的幫助。

我的希望是,我可以用函數的幫助來替換對象參數的排序字符串參數。

//input for example: sort=-username 
Boolean isAscending = isAscending(sort) //return true or false 
var parameter = isSortStringInsideObject(sort) // 
if (isAscending) { 
    user.OrderBy(o => o.parameter).ToList(); 
} else { 
    user.OrderByDescending(o => o.parameter).ToList(); 
} 

這樣的參數可以在對象的每個參數。

我是.net內核中的新成員。所以我希望我沒有制定一個烏托邦的要求。

+0

反射可能在這裏有所幫助:https://stackoverflow.com/a/19276588/1462295 – BurnsBA

+2

你可以用某種方式使用反射,但說實話,除非有很多不同的屬性,你最好只使用一個大的switch語句 – mikelegg

+1

您可能已經試過了,但是您是否考慮過將System.Linq.Dynamic庫包含到您的項目中?這將允許你做動態(基於字符串)排序 – ullfindsmit

回答

2

像這樣的東西應該做的伎倆(使用反射):

var isAscending = GetIsAscending(sort); 
var pi = typeof(User).GetProperty(parameter); 
if (pi != null) 
    user = isAscending 
     ? user.OrderBy(a => pi.GetValue(a, null)) 
     : user.OrderByDescending(a => pi.GetValue(a, null)); 
0

我會盡量保持輸入,並使用帶有字符串的地圖funcs中,所以你可以查找值進來並將其映射。

var list = new List<Item> { new Item() { Name = "aob", Age = 11 }, new Item() {Name = "bob", Age = 10},}; 
var input = "-name"; 

var map = new Dictionary<string, Func<Item, object>>() 
{ 
    {"name", x => x.Name}, 
    {"age", x => x.Age} 
}; 

if (input.StartsWith('-')) 
{ 
    var orderby = map[input.Substring(1)]; 
    var orderedEnumerable = list.OrderByDescending(orderby); 
} 
else 
{ 
    var orderby = map[input]; 
    var orderedEnumerable = list.OrderBy(orderby); 
} 
0

有趣..這可能也與此有關使用System.Linq.Expression命名空間中動態創建傳遞給訂購或OrderByDescending,尤其是當許多可能的排序參數,預計一個FUNC。

E.g.之後我們有一個字符串參數

var parameter = isSortStringInsideObject(sort) 

它可以構建這樣的功能(T是用戶的類型):

Dictionary<string, PropertyInfo> properties = typeof(T).GetProperties().ToDictionary(pi => pi.Name); 
ParameterExpression parameterExpression = Expression.Parameter(typeof(T)); 
Expression expression = Expression.MakeMemberAccess(parameterExpression, properties[parameter]); 
Func<T, string> orderFunc = Expression.Lambda<Func<T, string>>(expression, parameterExpression).Compile(); 

看起來有點沉重:)但它可能是有效。