![](/img/trans.png)
[英]A linq statement with multiple group by columns not allowing a thenby
[英]LINQ How to use multiple ThenBy dynamically?
我不認為這會很難找到,但看起來似乎是這樣。 這是情況。
我有一個ApplySort方法,它接受從mvc頁面發布的3個參數。
private List<dynamic> ApplySort(List<dynamic> listToBeSorted, string sortBy, string sortOrder)
{
if (String.IsNullOrEmpty(sortBy))
sortBy = "createddate";
if (String.IsNullOrEmpty(sortOrder) || sortOrder.Trim() != "0")
sortOrder = "1"; // 1 = descending, 0 = ascending
if (sortOrder == "1")
{
switch (sortBy)
{
case "name":
listToBeSorted = listToBeSorted.OrderByDescending(a => a.name).ToList();
break;
case "assigned":
listToBeSorted = listToBeSorted.OrderByDescending(a => a.title).ToList();
break;
case "duedate":
listToBeSorted = listToBeSorted.OrderByDescending(a => a.end).ToList();
break;
case "status":
listToBeSorted = listToBeSorted.OrderByDescending(a => a.title).ToList();
break;
default:
listToBeSorted = listToBeSorted.OrderByDescending(a => a.title).ToList();
break;
}
}
else
{
// same code as in if-block, with just OrderBy calls instead of OrderByDescending
}
return listToBeSorted;
}
兩個問題:
1)方法似乎不必要很長(if和else塊內部的代碼非常相似)。
2) 我希望能夠使用多列進行排序。 sortBy param可以包含“name,title,createddate,status”之類的值。 因此,應用的排序應首先按名稱,然后按標題,然后按創建日期...依此類推。 我可以通過順序檢查params來使用ThenBy 。 但是如何基於param值動態應用ThenBy鏈 ,其中ThenBy的數量可以變化 。
string[] sortParams = sortBy.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
listToBeSorted.OrderBy(i=>i.sortParams[0]).ThenBy(j=>j.sortParams[1]).ThenBy(k=>k.sortParams[2])...(so on till sortParams.length)
我該怎么做? 另外,我如何使用sortOrder參數在同一行中升序或降序排序,而不是使用if-else。
您可以使用Func<string, IComparable>
映射到類的屬性來創建字典。
public class ItemWithProperty
{
public string Property { get; set; }
}
public static void Main()
{
Dictionary<string, Func<ItemWithProperty, IComparable>> stringPropertyMap = new Dictionary<string, Func<ItemWithProperty, IComparable>>()
{
{"param1", item => item.Property}
};
List<ItemWithProperty> toBeOrdered = new List<ItemWithProperty>();
string[] parameters = {"param1"};
var sorted = toBeOrdered.OrderBy(stringPropertyMap[parameters[0]]);
}
如果更改方法簽名,則使用此方法:
private static IEnumerable<dynamic> ApplySort(IEnumerable<dynamic> listToBeSorted, ICollection<KeyValuePair<string, string>> sorters)
{
var orderBy = (sorters == null || sorters.Count == 0) ? new KeyValuePair<string, string>("createddate", "1") : sorters.First();
var thenBys = (sorters == null || sorters.Count == 1) ? new List<KeyValuePair<string, string>>() : sorters.Except(Enumerable.Repeat(orderBy, 1));
var orderedEnumerable = orderBy.Value == "1"
? listToBeSorted.OrderBy(x => GetPropertyValue(x, orderBy.Key))
: listToBeSorted.OrderByDescending(x => GetPropertyValue(x, orderBy.Key));
orderedEnumerable = thenBys.Aggregate(orderedEnumerable, (current, thenBy) => thenBy.Value == "1"
? current.ThenBy(x => GetPropertyValue(x, thenBy.Key))
: current.ThenByDescending(x => GetPropertyValue(x, thenBy.Key)));
return orderedEnumerable.ToList();
}
private static object GetPropertyValue(dynamic obj, string propName)
{
Type t = obj.GetType();
return t.GetProperty(propName).GetValue(obj, null);
}
試試:
static void Main(string[] args)
{
var list = new List<dynamic>();
list.Add(new { name = "Billy" });
list.Add(new { name = "Johnny" });
list.Add(new { name = "Ali" });
var list2 = ApplySort(list, new List<KeyValuePair<string, string>>(new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("name", "1") }));
foreach (var o in list2)
{
Console.WriteLine(o.name);
}
Console.ReadLine();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.