虽然我很难找到与此相关的任何文档,但似乎 DataTable 类本身与顺序无关 - 也就是说,它将按照记录的加载顺序显示记录(在DataTable 通过适配器加载的情况,这将是结果集中行的顺序)。
可以按特定的排序顺序提取记录(如下所示:Sorting rows in a data table)并使用此新序列中的行创建一个新的DataTable。这似乎是大多数人获得某种效果的方式。
不过,Select 方法将其排序条件作为字符串 (http://msdn.microsoft.com/en-us/library/way3dy9w(v=vs.110).aspx) 接受,这意味着排序条件仅限于类支持的条件。表明支持的所有文档都是列名和方向。
由于您想要的是自定义排序,而不是基本的逐列排序,因此基础DataTable 似乎没有处理此内置的机制。我希望在您的场景中需要编写一些代码来从DataTable 中提取记录,并使用自定义排序器对它们进行排序(使用 LINQ 的 OrderBy 和提取数据的函数可能会成功) ,然后将它们插入到您的代码以后使用的新 DataTable 中。
作为这种方法的一个例子:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
DataTable inputDataTable = CreateInputDataTable();
Console.WriteLine("Input data table: ");
PrintDataTable(inputDataTable);
DataTable outputDataTable = CustomSortDataTable(inputDataTable);
Console.WriteLine("Sorted data table: ");
PrintDataTable(outputDataTable);
}
private static DataTable CustomSortDataTable(DataTable inputDataTable)
{
DataRow[] rows = inputDataTable.Select();
IComparer<string> animalTypeComparer = new AnimalTypeComparer();
IEnumerable<DataRow> sortedRows = rows.OrderBy(x => x["AnimalType"].ToString(), animalTypeComparer);
DataTable result = new DataTable();
result.Columns.Add("ID");
result.Columns.Add("AnimalType");
foreach(DataRow row in sortedRows)
{
result.ImportRow(row);
}
return result;
}
private static void PrintDataTable(DataTable inputDataTable)
{
foreach(DataRow row in inputDataTable.Rows)
{
Console.WriteLine("({0}, {1})", row["ID"], row["AnimalType"]);
}
}
private static DataTable CreateInputDataTable()
{
DataTable result = new DataTable();
result.Columns.Add("ID");
result.Columns.Add("AnimalType");
DataRow toInsert = result.NewRow();
toInsert["ID"] = 1;
toInsert["AnimalType"] = "Cat";
result.Rows.Add(toInsert);
toInsert = result.NewRow();
toInsert["ID"] = 2;
toInsert["AnimalType"] = "Cat";
result.Rows.Add(toInsert);
toInsert = result.NewRow();
toInsert["ID"] = 3;
toInsert["AnimalType"] = "Bird";
result.Rows.Add(toInsert);
toInsert = result.NewRow();
toInsert["ID"] = 4;
toInsert["AnimalType"] = "Bird";
result.Rows.Add(toInsert);
toInsert = result.NewRow();
toInsert["ID"] = 5;
toInsert["AnimalType"] = "Dog";
result.Rows.Add(toInsert);
toInsert = result.NewRow();
toInsert["ID"] = 6;
toInsert["AnimalType"] = "Dog";
result.Rows.Add(toInsert);
toInsert = result.NewRow();
toInsert["ID"] = 7;
toInsert["AnimalType"] = "Hamster";
result.Rows.Add(toInsert);
toInsert = result.NewRow();
toInsert["ID"] = 8;
toInsert["AnimalType"] = "Hamster";
result.Rows.Add(toInsert);
return result;
}
}
class AnimalTypeComparer : IComparer<string>
{
private static readonly string[] AnimalTypes = {"Hamster", "Bird", "Cat", "Dog"};
#region Implementation of IComparer<in string>
/// <summary>
/// Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.
/// </summary>
/// <returns>
/// A signed integer that indicates the relative values of <paramref name="x"/> and <paramref name="y"/>, as shown in the following table.Value Meaning Less than zero<paramref name="x"/> is less than <paramref name="y"/>.Zero<paramref name="x"/> equals <paramref name="y"/>.Greater than zero<paramref name="x"/> is greater than <paramref name="y"/>.
/// </returns>
/// <param name="x">The first object to compare.</param><param name="y">The second object to compare.</param>
public int Compare(string x, string y)
{
return Array.IndexOf(AnimalTypes, x).CompareTo(Array.IndexOf(AnimalTypes, y));
}
#endregion
}
}
运行它会打印出以下内容:
Input data table:
(1, Cat)
(2, Cat)
(3, Bird)
(4, Bird)
(5, Dog)
(6, Dog)
(7, Hamster)
(8, Hamster)
Sorted data table:
(7, Hamster)
(8, Hamster)
(3, Bird)
(4, Bird)
(1, Cat)
(2, Cat)
(5, Dog)
(6, Dog)