最近在对DataTable的数据做处理的时候,需要排序,就用到了DataTable的Select方法。出现了很多问题
1、单列排序时:如果排序列为字符型的,就会按字符进行大小比较排序,例如24比100大,整形的没有问题
2、在多列排序时Select("1=1","col1,col2,col3,col4"),第一个是字符型的(里面可能有NULL值),后三个是整形的(里面可能有NULL值),发现排序就乱掉了,网上找了很多资料没有找到解决方案,一气之下自己写了个排序方法
/// <summary>
/// 排序
/// </summary>
/// <param name="dt">需处理的DataTable</param>
/// <param name="filter">过滤条件</param>
/// <param name="sort">排序条件</param>
/// <returns></returns>
public DataTable QuickSortAsc(DataTable dt, string filter, string sort)
{
DataRow[] rows = dt.Select(filter);
string[] cols = sort.Split(',');
QuickSortAsc(rows, 0, rows.Length - 1, 0, cols);
DataTable dtRtn = dt.Clone();
foreach (DataRow item in rows)
{
dtRtn.ImportRow(item);
}
return dtRtn;
}
/// <summary>
/// 排序
/// </summary>
/// <param name="rows">需排序数组</param>
/// <param name="left">开始数组索引(从0开始)</param>
/// <param name="right">结束数组索引(从0开始)</param>
/// <param name="index">排序字段数组开始索引</param>
/// <param name="cols">排序列(多列)</param>
private void QuickSortAsc(DataRow[] rows, int left, int right, int index, string[] cols)
{
if (cols.Length > 0 && index <= cols.Length - 1)
{
QuickSortAsc(rows, left, right, cols[index]);//单列排序
if (cols.Length > 1)//多列排序
{
string temp = String.Empty;
int start = left;
int end = left;
for (int j = left; j <= right; j++)//针对所有行
{
if (rows[j][cols[index]].ToString().Equals(temp))
{
end++;
}
else
{
if (start < end)
{
QuickSortAsc(rows, start, end - 1, index + 1, cols);//单列排序
}
start = j;
}
if (start < end && end == right)//到最后了该条件下所有都一样
{
QuickSortAsc(rows, start, right, index + 1, cols);//单列排序
}
temp = rows[j][cols[index]].ToString();
}
}
}
}
/// <summary>
/// 排序
/// </summary>
/// <param name="rows">排序的DataRow数组</param>
/// <param name="left">开始数组索引(从0开始)</param>
/// <param name="right">结束数组索引(从0开始)</param>
/// <param name="sortCol">排序列(单列)</param>
private void QuickSortAsc(DataRow[] rows, int left, int right, string sortCol)
{
if (left < right)
{
for (int i = left; i <= right; i++)
{
for (int j = left; j <= right - 1 - (i - left); j++)
{
if (IsBigger(rows[j][sortCol], rows[j + 1][sortCol]))
{
DataRow temp = rows[j];
rows[j] = rows[j + 1];
rows[j + 1] = temp;
}
}
}
}
}
/// <summary>
/// 判断第一个参数是否大于第二个参数
/// </summary>
/// <param name="ob1"></param>
/// <param name="ob2"></param>
/// <returns></returns>
private bool IsBigger(object ob1, object ob2)
{
if (ob1 is Int16 && ob2 is Int16)
{
if (Convert.ToInt16(ob1) > Convert.ToInt16(ob2))
{
return true;
}
else
{
return false;
}
}
else if (ob1 is Int32 && ob2 is Int32)
{
if (Convert.ToInt32(ob1) > Convert.ToInt32(ob2))
{
return true;
}
else
{
return false;
}
}
else if (ob1 is Int64 && ob2 is Int64)
{
if (Convert.ToInt64(ob1) > Convert.ToInt64(ob2))
{
return true;
}
else
{
return false;
}
}
else if (ob1 is String && ob2 is String)
{
if (String.Compare(ob1.ToString(), ob2.ToString()) > 0)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
该方法只是经过简单的测试,欢迎大家提出宝贵意见
至于这个Select方法排序的问题,大家知道原因的大神,欢迎留言