Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ如何动态使用多个ThenBy?_C#_.net_Linq_Sorting - Fatal编程技术网

C# LINQ如何动态使用多个ThenBy?

C# LINQ如何动态使用多个ThenBy?,c#,.net,linq,sorting,C#,.net,Linq,Sorting,我不认为这会是如此罕见的发现,但它似乎是。情况是这样的 我有一个ApplySort方法,它接收从mvc页面发布的3个参数 private List<dynamic> ApplySort(List<dynamic> listToBeSorted, string sortBy, string sortOrder) { if (String.IsNullOrEmpty(sortBy)) sortBy = "createdd

我不认为这会是如此罕见的发现,但它似乎是。情况是这样的

我有一个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;
    }

我该怎么做?另外,我还可以如何使用sortOrder参数在同一行中按升序或降序排序,而不是使用if-else。

您可以创建映射到类属性的
Func
字典

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]]);
}
公共类ItemWithProperty
{
公共字符串属性{get;set;}
}
公共静态void Main()
{
Dictionary stringPropertyMap=新字典()
{
{“param1”,item=>item.Property}
};
List TOBEORDED=新列表();
字符串[]参数={“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);
    }
private static IEnumerable ApplySort(IEnumerable listtoberted,ICollection-sorter)
{
var orderBy=(sorter==null | | sorter.Count==0)?新的KeyValuePair(“createddate”,“1”):sorter.First();
var thenBys=(sorter==null | | sorter.Count==1)?new List():sorter.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.thenBy递减(x=>GetPropertyValue(x,thenBy.Key));
return orderedEnumerable.ToList();
}
私有静态对象GetPropertyValue(动态对象,字符串propName)
{
类型t=obj.GetType();
返回t.GetProperty(propName).GetValue(obj,null);
}
尝试:

static void Main(字符串[]args)
{
var list=新列表();
添加(新的{name=“Billy”});
添加(新的{name=“Johnny”});
添加(新的{name=“Ali”});
var list2=ApplySort(列表,新列表(新列表{new KeyValuePair(“name”,“1”)}));
foreach(列表2中的变量o)
{
控制台写入线(o.name);
}
Console.ReadLine();
}

Google for“Dlinq”,它将允许您执行
。然后通过(新字符串[])
。虽然不是完全重复,但可能会给您一些启发。它使用枚举而不是字符串来定义搜索属性,但这不应该是一个问题。对于您的场景,似乎有一个属性名称和相应lambda的字典可以帮助您消除所有冗余。可能是重复的,但即使这样,我也必须为sortParams中的每个项调用stringPropertyMap.Add(),不是吗???只需调用一次就可以将类的IComparable属性映射到字符串值。然后可以链接orderby,然后使用所述的参数。实际上,您应该使用IComparable而不是对象编辑的我的答案。@MrClan实际上添加()在我的代码中是不必要的,因为我用值初始化了dict
    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();

    }