OriginalGriff
Во-первых, не делайте этого так, это имеет множество проблем.
1) это ленивый способ сделать это, который потенциально оставляет вас широко открытыми для атаки SQL-инъекций, которая может уничтожить всю вашу базу данных. Вместо этого всегда используйте параметризованные запросы.
Когда вы объединяете строки, вы вызываете проблемы, потому что SQL получает такие команды, как:
SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
Цитата, добавленная пользователем, завершает строку в том, что касается SQL, и вы получаете проблемы. Но могло быть и хуже. Если я приду и наберу вместо этого: "x';DROP TABLE MyTable;--", то SQL получит совсем другую команду:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Которые SQL видит как три отдельные команды:
SELECT * FROM MyTable WHERE StreetAddress = 'x';
Совершенно правильный выбор
DROP TABLE MyTable;
Вполне допустимая команда "удалить таблицу"
--'
А все остальное-это комментарии.
Так оно и происходит: выбирает любые совпадающие строки, удаляет таблицу из базы данных и игнорирует все остальное.
Поэтому предоставление метода для чтения из БД, который принимает выбранную строку, просто опасно!
2) поскольку вы создаете объект SQLCommand в отдельном методе, нет никакой гарантии, что команда будет закрыта, как и соединение - на самом деле ваш код не закрывает считыватель, если в нем нет строк.
Создание команды и встроенного считывателя позволяет использовать
using
блоки, чтобы убедиться, что они закрыты и утилизированы, когда они выходят за рамки - и это уменьшает вероятность возникновения проблем позже.
3) что приводит нас к следующей проблеме: поскольку вы совместно используете соединение, если какая - либо часть вашего кода "забывает" закрыть возвращаемый считыватель, то соединение постоянно занято им-и следующая попытка запроса потерпит неудачу, потому что считыватель открыт на соединении, и SQL не позволит вам это сделать. Затем вы должны искать свой код в любом направлении, которое может оставить читателя открытым ...
4) Не указывайте SEQUENTIAL_ACCESS, если он вам действительно не нужен - в этом случае никогда не используйте SELECT*, потому что он возвращает все столбцы, нужны они вам или нет. Поскольку последовательный доступ предназначен только для очень-очень больших столбцов данных, зачем возвращать столбцы, которые вы не собираетесь использовать, и тратить всю эту пропускную способность? Скорее всего, это также приводит к сбою теста HasRows, поскольку вам приходится по-разному обрабатывать данные, когда вы их указываете.