之前网上搜索的相关方法都是使用了反射的方法来动态获取字段,以实现动态linq排序,但是因为项目组觉得此方法效率低下,所以不予采纳。
所以有了以下代码
public interface IBase{ dynamic GetField(string field); } public class Employee : IBase { public int ID { get; set; } public string FName { get; set; } public int Age { get; set; } public char Sex { get; set; } public dynamic GetField(string field) { switch (field.ToUpper()) { case "ID": return ID; case "FNAME": return FName; case "AGE": return Age; case "SEX": return Sex; default: return ID; } } }
这是实体类,缺点是必须实现接口方法GetField,但这也是重点。
以下是对应的排序方法
/// <summary> /// 对结果集进行排序 /// </summary> /// <param name="source">结果集</param> /// <param name="dict">参数列表KEY:OrderBy Ascending VALUE:以,分隔</param> /// <returns></returns> protected List<IBase> OrderBy(List<IBase> source, Dictionary<string, string> dict) { if (dict.ContainsKey("OrderBy")) { try { string[] Order = dict["OrderBy"].Split(','); string[] ascend = dict.ContainsKey("Ascending") ? dict["Ascending"].Split(',') : new string[] { "1" }; IOrderedEnumerable<IBase> current = null; if (ascend[0] == "1") current = source.OrderBy(p => p.GetField(Order[0])); else current = source.OrderByDescending(p => p.GetField(Order[0])); int index = 0; for (int i = 1; i < Order.Length; i++) { index = ascend.Length > i ? i : ascend.Length - 1; if (ascend[index] == "1") current = current.ThenBy(p => p.GetField(Order[i])); else current = current.ThenByDescending(p => p.GetField(Order[i])); } return current.ToList(); } catch { } } return source; }
以下是测试方法
public void LinqOrder() { var empList = new List<Employee>(); Random r = new Random(); int length = 10000000; Console.WriteLine(string.Format("开始装载数据({0})...", length)); Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < length; i++) { empList.Add(new Employee() { ID = i, FName = "A" + i, Age = r.Next(0, 100), Sex = r.Next(0, 1) == 1 ? 'F' : 'M' }); } sw.Stop(); Console.WriteLine(string.Format("{0}条数据装载完成,时间为:{1}", length, sw.ElapsedMilliseconds)); Console.WriteLine("开始转换数据,Employee to IBase"); sw = new Stopwatch(); sw.Start(); var list = empList.ToList<IBase>(); sw.Stop(); Console.WriteLine(string.Format("{0}条数据转换,Employee to IBase,时间为:{1}", length, sw.ElapsedMilliseconds)); Dictionary<string, string> dict = new Dictionary<string, string>(); dict["OrderBy"] = "Age,Sex"; dict["Ascending"] = "1,1"; Console.WriteLine("开始排序"); sw = new Stopwatch(); sw.Start(); OrderBy(list, dict); sw.Stop(); Console.WriteLine(string.Format("{0}条数据使用dynamic排序时间为:{1}", length, sw.ElapsedMilliseconds)); Console.WriteLine("开始普通排序"); sw = new Stopwatch(); sw.Start(); empList.OrderBy(p => p.Age).ThenBy(p => p.Sex).ToList(); sw.Stop(); Console.WriteLine(string.Format("{0}条数据使用字段排序时间为:{1}", length, sw.ElapsedMilliseconds)); }
以下是测试结果