发现了DataTable的一个bug
以下函数可保留选定列:public static void FilterColumn(this DataTable table, params string[] reserveColumnNames)
{
HashSet<string> needColNameSet = new HashSet<string>(reserveColumnNames);
List<string> colNameList = new List<string>(table.Columns.Count);
foreach (DataColumn col in table.Columns)
colNameList.Add(col.ColumnName);
table.AcceptChanges();
foreach (string columnName in colNameList)
{
if (needColNameSet.Contains(columnName) == false)
table.Columns.Remove(columnName);
}
table.AcceptChanges();
}
随便构建一个DataTable,如:
DataTable table = new DataTable();
table.Columns.Add("One",typeof(int));
table.Columns.Add("Two",typeof(int));
table.Columns.Add("Three",typeof(int));
执行:
DataRow[] rows = table.Select("Three=1");
无误,然后执行以下代码:
FilterColumn(table, "One", "Three");
再次执行:
DataRow[] rows = table.Select("Three=1");
报错:引发了“System.IndexOutOfRangeException”类型的异常 System.Data.DataRow[] {System.IndexOutOfRangeException}
StackTrack:
在 System.Data.Select.CompareClosestCandidateIndexDesc(Int32[] id)
在 System.Data.Select.FindClosestCandidateIndex()
在 System.Data.Select.SelectRows()
在 System.Data.DataTable.Select(String filterExpression) bug DataTable RemoveColumn Select --------------------编程问答-------------------- Three列 已经删除 还做什么筛选? --------------------编程问答--------------------
没有啊,"One"和"Three"是保留的列,"two"被删除了。 --------------------编程问答-------------------- 完全copy你的代码运行了一下,没发现报错 --------------------编程问答-------------------- 重复索引么
不是已经有Three 再加个就溢出了 --------------------编程问答-------------------- 没抱错的飘过1` --------------------编程问答-------------------- 把foreach (string columnName in colNameList) { if (needColNameSet.Contains(columnName) == false) table.Columns.Remove(columnName); } table.AcceptChanges();
这段代码注释,再调试看看!! --------------------编程问答-------------------- 看错了,不好意思
试了一下,代码应该没有问题吧 --------------------编程问答-------------------- 可以确定的是:
1。 从你目前给出的代码,是没有错误的
2。 这也不是什么datatable的BUG
namespace ConsoleApplication2--------------------编程问答-------------------- 经过测试没发现报错! --------------------编程问答--------------------
{
static class Program
{
static void Main(string[] args)
{
DataTable table = new DataTable();
table.Columns.Add("One", typeof(int));
table.Columns.Add("Two", typeof(int));
table.Columns.Add("Three", typeof(int));
DataRow[] rows = table.Select("Three=1");
foreach (DataColumn item in table.Columns)
{
Console.WriteLine(item.ColumnName);
}
// table.FilterColumn("One", "Three"); //recommand you use FilterColumn this way
FilterColumn(table, "One", "Three");
foreach (DataColumn item in table.Columns)
{
Console.WriteLine(item.ColumnName);
}
DataRow[] rows1 = table.Select("Three=1");
foreach (DataColumn item in table.Columns)
{
Console.WriteLine(item.ColumnName);
}
Console.ReadKey();
}
public static void FilterColumn(this DataTable table, params string[] reserveColumnNames)
{
HashSet<string> needColNameSet = new HashSet<string>(reserveColumnNames);
List<string> colNameList = new List<string>(table.Columns.Count);
foreach (DataColumn col in table.Columns)
colNameList.Add(col.ColumnName);
table.AcceptChanges();
foreach (string columnName in colNameList)
{
if (needColNameSet.Contains(columnName) == false)
table.Columns.Remove(columnName);
}
table.AcceptChanges();
}
}
}
Sorry,帖子有误,应该是从DB load出来的table,
更正代码如下:
DataTable table = new DataTable();
using (IDataReader rd = GetTableFromDB())
{
table.Load(rd);
}
DB是一个含One,Two,Three散列的表 --------------------编程问答--------------------
谢谢,是我说错了,应该是从DB load出来的table,见:
例如:
DataTable table = new DataTable();
using (IDataReader rd = GetTableFromDB())
{
table.Load(rd);
}
然后执行删除列的操作,删除后如果对原始列的顺序有影响的(如中间某列),select就就怎么样都不能执行。谢谢提醒,正在看table.Load给列加了什么特别的属性。 --------------------编程问答-------------------- --------------------编程问答--------------------
能不能QQ回我一句 --------------------编程问答-------------------- 为什么我运行没报错? --------------------编程问答--------------------