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));
        }

  以下是测试结果

posted on 2013-11-15 18:16  我是流氓  阅读(1745)  评论(14编辑  收藏  举报

导航