• linq 动态排序,不使用反射


    之前网上搜索的相关方法都是使用了反射的方法来动态获取字段,以实现动态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));
            }
    

      以下是测试结果

  • 相关阅读:
    2050编程赛 冰水挑战 HDU 6495
    Codeforces Round #565 (Div. 3) F.Destroy it!
    ADO 查询
    Default parameters (Function) – JavaScript 中文开发手册
    Errors: Deprecated expression closures (Errors) – JavaScript 中文开发手册
    JavaScript RegExp 对象
    在Java中为静态最终变量赋值
    FE_INVALID (Numerics) – C 中文开发手册
    getter-return (Rules) – Eslint 中文开发手册
    no-irregular-whitespace (Rules) – Eslint 中文开发手册
  • 原文地址:https://www.cnblogs.com/liumang/p/3425908.html
Copyright © 2020-2023  润新知