Проблема с таблицей данных Выберите оператор - PullRequest
12 голосов
/ 07 марта 2012

Следующая строка VB, где _DSversionInfo - это DataSet, не возвращает строк:

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

но проверка показывает, что таблица содержит строки с FileID's 92, 93, 94, 90, 88, 89, 215, 216. Все столбцы таблицы имеют тип string.

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

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

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

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

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

Ответы [ 4 ]

20 голосов
/ 07 марта 2012

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

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

Создайте DataTable и в строковом столбце '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 голосов
/ 07 марта 2012

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 голосов
/ 15 декабря 2017

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

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

var results2 = table.Select("Convert(NumbersAsString , 'System.Decimal') = 74.0")
0 голосов
/ 08 декабря 2014
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();
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...