2012-03-07 3 views
12

Следующая VB линии, где _DSversionInfo является DataSet, не возвращает ни одной строки:Проблема с таблицей данных Выбор заявления

_DSversionInfo.Tables("VersionInfo").Select("FileID=88") 

но осмотр показывает, что таблица содержит строки с FILEID-х годах 92, 93, 94, 90, 88, 89, 215, 216. Столбцы таблицы представляют собой строку типа.

Дальнейшие исследования показали, что с использованием идентификатора 88, 215 и 216 будут возвращаться только строки, если это число указано.

_DSversionInfo.Tables("VersionInfo").Select("FileID='88'") т.е.

Все остальные строки работают независимо от того, указан номер или нет.

Кто-нибудь получил объяснение, почему это произойдет для некоторых номеров, но не для других? Я понимаю, что цифры должны быть указаны только не потому, что какая-то работа и другие нет?

Я обнаружил это в некотором коде VB.NET, но (несмотря на мой указательный палец) не думаю, что это VB.NET.

+1

Вы уверены, что значение в таблице действительно '88', а не что-то вроде' 88' или с каким-либо другим дополнением? – Marc

+0

Имеет ли '_DSversionInfo.Tables (« VersionInfo »). Выберите (« FileID = 92 »)' возвращать любые строки? –

+0

Почти ничего не характерно для C# или VB.NET. Они используют одну и ту же платформу .NET Framework. –

ответ

20

В соответствии с MSDN documentation on building expressions строки всегда должны быть указаны. Несоблюдение этого приводит к непредсказуемому поведению, которое может привести к непредсказуемым последствиям ... Вы должны процитировать свои строки чисел, чтобы получить предсказуемое и правильное поведение, как указано в документации.

Я encounted, что вы описываете в прошлом, и своего рода пытались понять это - здесь, поп открыть свой любимый редактор .NET и попробуйте следующее:

Создание DataTable, и в string column 'Stuff' этого DataSet, вставьте строки в следующем порядке: «6», «74», «710» и «Выбрать» с помощью выражения фильтра «Stuff = 710». Вы получите 1 строку назад. Теперь измените первую строку на любое число больше 7 - внезапно, вы получите 0 строк назад.

Пока номера упорядочены в порядке убывания, используя логику строкового упорядочения (т. Е. 7 приходит после 599), неуправляемый запрос работает.

Я думаю, что это ограничение, как DataSet фильтр выражения обрабатываются, и он не должен был работать таким образом ...

Кодекс:

 
      // Unquoted filter string bizzareness. 
      var table = new DataTable(); 

      table.Columns.Add(new DataColumn("NumbersAsString", typeof(String))); 

      var row1 = table.NewRow(); row1["NumbersAsString"] = "9"; table.Rows.Add(row1); // Change to '66 
      var row2 = table.NewRow(); row2["NumbersAsString"] = "74"; table.Rows.Add(row2); 
      var row4 = table.NewRow(); row4["NumbersAsString"] = "90"; table.Rows.Add(row4); 
      var row3 = table.NewRow(); row3["NumbersAsString"] = "710"; table.Rows.Add(row3); 

      var results = table.Select("NumbersAsString = 710"); // Returns 0 rows. 
      var results2 = table.Select("NumbersAsString = 74"); // Throws exception "Min (1) must be less than or equal to max (-1) in a Range object." at System.Data.Select.GetBinaryFilteredRecords() 

Заключение : Основываясь на тексте исключения в последнем случае, похоже, какое-то странное литье происходит внутри выражений фильтра, что не гарантируется. Явное размещение одинарных кавычек вокруг значения, для которого вы запрашиваете, позволяет избежать этой проблемы, позволяя .NET знать, что это литерал.

8

DataTable строит индекс в столбцах, чтобы сделать запросы Select() быстрыми. Этот индекс сортируется по значению, затем он использует двоичный поиск для выбора диапазона записей, соответствующих выражению запроса.

Таким образом, записи будут отсортированы следующим образом: 215,216,88,89,90,92,93,94. Бинарный поиск выполняется с их целым числом (согласно нашему выражению фильтра) не может найти определенные записи, поскольку он предназначен только для поиска правильно отсортированных коллекций.

Он индексирует данные как строку и ищет двоичный поиск как номер. См. Ниже объяснение.

 string[] strArr = new string[] { "115", "118", "66", "77", "80", "81", "82" }; 
     int[] intArr = new int[] { 215, 216, 88, 89, 90, 92, 93, 94 }; 
     int i88 = Array.BinarySearch(intArr, 88); //returns -ve index 
     int i89 = Array.BinarySearch(intArr, 89); //returns +ve index 

Это должно быть ошибкой в ​​рамках.

+0

Извините, и ваш, и ответ Vals хороши, но Я должен был выбрать один. – Neil

0
this error usually comes due to invalid data table column type in which you are going to search 
i got this error when i was using colConsultDate instead of Convert(colConsultDate, 'System.DateTime') 
because colConsultDate was a data table column of type string which i must have to convert into System.DateTime therefor your search query should be like 

    string query = "Convert(colConsultDate, 'System.DateTime') >= #" + sdateDevFrom.ToString("MM/dd/yy") + "# AND Convert(colConsultDate, 'System.DateTime') <= #" + sdateDevTo.ToString("MM/dd/yy") + "#"; 
    DataRow[] dr = yourDataTable.Select(query); 
    if (dr.Length > 0) 
    { 
     nextDataTabel = dr.CopyToDataTable(); 
    } 
0

@ Вал Аккапедди просто хочу добавить что-либо к вашему ответу.

Если вы сделаете что-то подобное, это будет полезно, когда вам придется использовать операторы сравнения. потому что вы ставите кавычки около 74, он будет рассматриваться как строка. пожалуйста, посмотрите сами, написав код. Comparison operators (десятичное только для справки, вы можете добавить нужный тип данных вместо.)

var results2 = table.Select("Convert(NumbersAsString , 'System.Decimal') = 74.0") 
Смежные вопросы