2011-03-31 70 views
6

的DataTable.Select()函数,像这样的过滤器返回错误的行...为什么DataTable.Select()返回错误的行?

“booleanColumn1和booleanColumn2和GuidColumn1 = '00000000-0000-0000-0000-000000000000')”

制作事实上,对这种格式的任何修改都会修复它(请参阅示例)。在dataView上使用相同的过滤器可以正常工作。我很想将其更改为

“booleanColumn1 = 1 AND booleanColumn2 = 1 AND GuidColumn1 = '00000000-0000-0000-0000-000000000000')”

,并宣布它固定(文档只字不提是“A”还是“A = 1”是布尔列的正确语法)。但责备可以轻易放在Guid专栏上。在我重新访问数百个在我们的代码库中使用DataTable.Select()的地方之前,我希望看看是否有人知道发生了什么。

DataTable dt = new DataTable("dt"); 
dt.Columns.AddRange(new DataColumn[] 
{ 
    new DataColumn("ID", typeof(Guid)), 
    new DataColumn("A", typeof(bool)), 
    new DataColumn("B", typeof(bool)) 
}); 

dt.Rows.Add(Guid.Empty, false, true); 

// this incorrectly returns a row 
Debug.WriteLine(dt.Select("B AND A AND ID = '00000000-0000-0000-0000-000000000000'").Length); 

// yet it's fine for a DataView (correctly returns 0 rows) 
DataView dv = new DataView(dt); 
dv.RowFilter = "B AND A AND ID = '00000000-0000-0000-0000-000000000000'"; 
Debug.WriteLine(dv.Count); 

// these correctly return 0 rows 
Debug.WriteLine(dt.Select("B AND A").Length); 
Debug.WriteLine(dt.Select("B AND A AND CONVERT(ID, 'System.String') = '00000000-0000-0000-0000-000000000000'").Length); 
Debug.WriteLine(dt.Select("A AND B AND ID = '00000000-0000-0000-0000-000000000000'").Length); 
Debug.WriteLine(dt.Select("B = 1 AND A AND ID = '00000000-0000-0000-0000-000000000000'").Length); 
Debug.WriteLine(dt.Select("ID = '00000000-0000-0000-0000-000000000000' AND B AND A").Length); 
Debug.WriteLine(dt.Select("B AND (A AND ID = '00000000-0000-0000-0000-000000000000')").Length); 

// still wrong 
Debug.WriteLine(dt.Select("B AND A AND ID = '00000000-0000-0000-0000-000000000000'").Length); 
+0

的一个有趣特性此问题是如果您重新排列DataTable中的列,查询返回不同的结果。我试图将ID列从DataTable中的第一列移动到第三列,并且第一个Select()不像预期的那样返回任何行。 – 2011-04-01 13:56:22

回答

0

没有答案。

我修改了测试,使其更容易一些与工作,发现了更多的不正确:

A和B以及ID = '00000000-0000-0000-0000-000000000000'

B和A AND(ID ='0000000-0000-0000-0000-000000000000')

这看起来像是一个bug。你可能想把它带到微软Connnect。

using System; 
using System.Data; 
using System.Diagnostics; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     DataTable dt = new DataTable("dt") 
     { 
      Columns = 
      { 
       new DataColumn("ID", typeof(Guid)), 
       new DataColumn("A", typeof(bool)), 
       new DataColumn("B", typeof(bool)), 
      } 
     }; 

     dt.Rows.Add(Guid.Empty, false, false); 
     dt.Rows.Add(Guid.Empty, false, true); 
     dt.Rows.Add(Guid.Empty, true, false); 
     dt.Rows.Add(Guid.Empty, true, true); 

     Console.BackgroundColor = ConsoleColor.Black; 
     Console.Clear(); 
     Console.ForegroundColor = ConsoleColor.Green; 
     foreach (DataRow row in dt.Rows) 
      Console.WriteLine("ID = {0}, A = {1}, B = {2}", row["ID"], row["A"], row["B"]); 
     Console.WriteLine(); 

     // this incorrectly returns a row 
     Test(dt, "B AND A AND ID = '00000000-0000-0000-0000-000000000000'"); 

     // these correctly return 0 rows 
     Test(dt, "B AND A"); 
     Test(dt, "B AND A AND CONVERT(ID, 'System.String') = '00000000-0000-0000-0000-000000000000'"); 
     Test(dt, "A AND B AND ID = '00000000-0000-0000-0000-000000000000'"); 
     Test(dt, "B = 1 AND A AND ID = '00000000-0000-0000-0000-000000000000'"); 
     Test(dt, "ID = '00000000-0000-0000-0000-000000000000' AND B AND A"); 
     Test(dt, "B AND (A AND ID = '00000000-0000-0000-0000-000000000000')"); 
     Test(dt, "(B AND A AND ID = '00000000-0000-0000-0000-000000000000')"); 

     // still wrong 
     Test(dt, "B AND A AND ID = '00000000-0000-0000-0000-000000000000'"); 

     // also incorrect for both A = True and B = True 
     Test(dt, "B AND A AND (ID = '0000000-0000-0000-0000-000000000000')"); 

     if (Debugger.IsAttached) 
     { 
      Console.ForegroundColor = ConsoleColor.Gray; 
      Console.WriteLine(); 
      Console.WriteLine("Press any key to continue . . . "); 
      Console.ReadKey(); 
     } 

     Console.ResetColor(); 
     Console.Clear(); 
    } 

    public static void Test(DataTable dt, string filter) 
    { 
     Console.ForegroundColor = ConsoleColor.White; 
     Console.WriteLine(filter); 
     Console.ForegroundColor = ConsoleColor.Yellow; 
     Console.WriteLine(" DT = {0}, DV = {1}", 
      dt.Select(filter).Length, 
      new DataView { Table = dt, RowFilter = filter }.Count); 
    } 
} 
3

这绝对是一个bug,它看起来好像已经存在很长时间了。我发现this knowledgebase article描述了.Net框架1.1中完全相同的错误。

这似乎是第二个条件是完全忽略了,因为我发现下面的变化也返回一行:

dt.Select("B AND false AND ID = '00000000-0000-0000-0000-000000000000'") 
dt.Select("B AND 0 AND ID = '00000000-0000-0000-0000-000000000000'") 

然而,这正确返回0行:

dt.Select("B AND A AND A AND ID = '00000000-0000-0000-0000-000000000000'") 
+0

找到知识库文章+1 – 2011-03-31 20:42:47

相关问题