簡體   English   中英

LINQ如何動態使用多個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM