C# LINQ如何动态使用多个ThenBy?
我不认为这会是如此罕见的发现,但它似乎是。情况是这样的 我有一个ApplySort方法,它接收从mvc页面发布的3个参数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
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();
}