日期:2014-05-20  浏览次数:21149 次

linq对datatable多列排序
C# code
       private void TestSortLinq()
        {
            string idColumnName = "ID";
            string nameColumnName = "Name";
            string phoneColumnName="Phone";
            string addressColumnName="Address";
            DataTable testDT = new DataTable();
            testDT.Columns.AddRange(
                new DataColumn[] {
                new DataColumn(idColumnName,typeof(System.String)),
                new DataColumn(nameColumnName,typeof(System.String)),
                new DataColumn(phoneColumnName,typeof(System.String)),
                new DataColumn(addressColumnName,typeof(System.String))});

            
            for (int i = 0; i < 20; i++)
            {
                Random _rd = new Random(i);
                DataRow row = testDT.NewRow();
                row[idColumnName] = idColumnName + _rd.Next(i).ToString();
                row[nameColumnName] = nameColumnName + _rd.Next(i).ToString();
                row[phoneColumnName] = phoneColumnName + _rd.Next(i).ToString();
                row[addressColumnName] = addressColumnName + _rd.Next(i).ToString();
                testDT.Rows.Add(row);
            }
            testDT.TableName="testDT";

            IEnumerable<DataRow> rows = from p in testDT.AsEnumerable()
                                        select p;

            #region 没问题
            rows = rows.CopyToDataTable().AsEnumerable().OrderBy(s =>
                decimal.Parse(Regex.Match(s[idColumnName].ToString(), @"\d+").Value));

            testDT = rows.CopyToDataTable();
            #endregion
            #region 有问题
            rows = rows.CopyToDataTable().AsEnumerable().OrderBy(s => new
            {
                //虽然现在这里只写了两个,但是有可能是三个或者是四个或者是一个,请问这里怎么写成动态的orderby语句
                id = decimal.Parse(Regex.Match(s[idColumnName].ToString(), @"\d+").Value),
                name = decimal.Parse(Regex.Match(s[nameColumnName].ToString(), @"\d+").Value) 
            });
            testDT = rows.CopyToDataTable();
            #endregion
        }



大家看下我的代码就知道我说的什么了:1是为什么第二种写法会报错,2,如何写一个动态的orderby语句

------解决方案--------------------
var list = source.OrderBy(...);

if (条件1)
list = list.ThenBy(...);
if (条件2)
list = list.ThenBy(...);
...
------解决方案--------------------
C# code
 rows = rows.CopyToDataTable().AsEnumerable()
    .OrderBy(s =>decimal.Parse(Regex.Match(s[idColumnName].ToString(), @"\d+").Value))
    .ThenBy(s =>decimal.Parse(Regex.Match(s[nameColumnName].ToString(), @"\d+").Value));

------解决方案--------------------
用 var 关键字!!!

var query = dt.AsEnumerable().OrderBy(r => 1);

OrderBy完是 OrderedEnumerableRowCollection<T>
------解决方案--------------------
给你贴个main函数,通过设置Flag和str_c来动态指定排序的列,你试试看对不对
注:"ID2"大于"ID10"。。。郁闷了我很久。。。
C# code
        static void Main(string[] args)
        {
            string idColumnName = "ID";
            string nameColumnName = "Name";
            string phoneColumnName = "Phone";
            string addressColumnName = "Address";
            DataTable testDT = new DataTable();
            testDT.Columns.AddRange(
                new DataColumn[] {
                new DataColumn(idColumnName,typeof(System.String)),
                new DataColumn(nameColumnName,typeof(System.String)),
                new DataColumn(phoneColumnName,typeof(System.String)),
                new DataColumn(addressColumnName,typeof(System.String))});


            for (int i = 0; i < 20; i++)
            {
                Random _rd = new Random(i);
                DataRow row = testDT.NewRow();
                row[idColumnName] = idColumnName + _rd.Next(i).ToString();
                row[nameColumnName] = nameColumnName + _rd.Next(i).ToString();
                row[phoneColumnName] = phoneColumnName + _rd.Next(i).ToString();
                row[addressColumnName] = addressColumnName + _rd.Next(i).ToString();
                testDT.Rows.Add(row);
            }

            var query = from s in testDT.AsEnumerable() orderby new orderClass() { C1 = get_c1(s), C2 = get_c2(s), C3 = get_c3(s), C4 = get_c4(s) } select s;
            foreach (var r in query)
            {
                Console.Write(r[0].ToString() + "   ");
                Console.Write(r[1].ToString() + "   ");
                Console.Write(r[2].ToString() + "   ");
                Console.Write(r[3].ToString() + "   ");
                Console.WriteLine();
            }
            Console.ReadKey();
        }
        static private bool c1Flag = true;//控制是否依orderClass的第一项来排序
        static private bool c2Flag = false;
        static private bool c3Flag = false;
        static private bool c4Flag = true;
        static private string str_c1 = "ID";//控制排序的第一项对应的 属性名称
        static private string str_c2 = "Name";
        static private string str_c3 = "Phone";
        static private string str_c4 = "Address";
        static private string get_c4(DataRow s)
        {
            //在函数内部进行判断,控制返回值
            if (c4Flag)
            {
                return s[str_c4].ToString();
            }
            else
            {
                return "";
            }
        }

        static private string get_c3(DataRow s)
        {
            if (c3Flag)
            {
                return s[str_c3].ToString();
            }
            else
            {
                return "";
            }
        }

        static private string get_c2(DataRow s)
        {
            if (c2Flag)
            {
                return s[str_c2].ToString();
            }
            else
            {
                return "";
            }
        }
        static private string get_c1(DataRow s)
        {
            if (c1Flag)
            {
                return s[str_c1].ToString();
            }
            else
            {
                return "";
            }
        }
        class orderClass : IComparable<orderClass>
        {
            //c1, c2, c3, c4表示排序的优先顺序,当然,可以有c5,c6等等
            private string c1, c2, c3, c4;

            public string C4
            {
                get { return c4; }
                set { c4 = value; }
            }

            public string C3
            {
                get { return c3; }
                set { c3 = value; }
            }

            public string C2
            {
                get { return c2; }
                set { c2 = value; }
            }

            public string C1
            {
                get { return c1; }
                set { c1 = value; }
            }

            #region IComparable<AClass> 成员

            int IComparable<orderClass>.CompareTo(orderClass p)
            {
                if (c1.CompareTo(p.c1) != 0)
                {
                    return c1.CompareTo(p.c1);
                }
                else if (c2.CompareTo(p.c2) != 0)
                {
                    return c2.CompareTo(p.c2);
                }
                else if (c3.CompareTo(p.c3) != 0)
                {
                    return c3.CompareTo(p.c3);
                }
                else
                {
                    return c4.CompareTo(p.c4);
                }
            }

            #endregion
        }