C # статический класс базы данных?

У меня есть класс базы данных, который включает следующие методы:

  • public bool ExecuteUDIQuery (строковый запрос) // UDI = Обновить Удалить Вставить
  • public bool ExecuteSelectQuery (строковый запрос)
  • public bool ExecuteSP (строка sp, строка [,] parms)
  • public int ExecuteSPReturnValue (строка sp, string [,] parms)

Результаты методов хранятся в частных наборах данных или таблицах данных. Эти объекты определены как геттеры.

Существует около 10 классов, которые используют класс Database. Каждый класс создает объект класса Database. Теперь я думал сделать класс базы данных статическим. Это хорошая идея? Если да, то почему? Почему бы и нет?


person Martijn    schedule 12.03.2009    source источник


Ответы (8)


Если я понимаю, у класса базы данных есть какие-то свойства, в которых хранится результат запроса? Если это так, вы не можете сделать их статическими, поскольку это не является потокобезопасным. Если результат запроса сохраняется в этих свойствах, что произойдет, если второй запрос будет выполняться сразу после первого? Он будет храниться в той же статической переменной. То же самое и с веб-приложением: результат просмотра сайта другим пользователем изменит результаты первого пользователя.

РЕДАКТИРОВАТЬ: Подводя итог, НЕ делайте класс статическим, когда вы сохраняете результат запросов в статических переменных, особенно когда класс используется на веб-сайте, поскольку значение свойств будет совместно использоваться всеми посетителями вашего веб-сайта. Если 20 посетителей выполняют запрос одновременно, посетитель 1 увидит результаты запроса посетителя 20.

person Razzie    schedule 12.03.2009
comment
Я создаю сайт. Итак, если я вас правильно понимаю, когда, скажем, 20 посетителей запрашивают другую страницу (а мой класс db является статическим), все идет не так, верно? - person Martijn; 12.03.2009
comment
Да вы правильно поняли. Если класс статический, свойства будут совместно использоваться приложением. Итак, если 20 посетителей выполняют запрос к базе данных, свойство будет содержать результат последнего запроса, выполненного посетителем номер 20. - person Razzie; 12.03.2009

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

Если вы проведете рефакторинг класса Database для возврата наборов данных при вызове метода, вы можете сделать его статическим: в классе Database не останется информации о состоянии.

Но поскольку это не так: нет, не делайте класс статическим.

person Inferis    schedule 12.03.2009
comment
Я согласен с Inferis. Альтернативой может быть создание класса фасада, который упрощает доступ к классам базы данных. - person Statement; 12.03.2009

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

Итак, я согласен с другими, не делайте из этого статический класс.

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

Изменить:
Я видел в комментарии, что вы хотите использовать свой класс на веб-сайте. В таком случае вам ДЕЙСТВИТЕЛЬНО не следует этого делать. Со статическим классом базы данных вы сможете безопасно обслуживать только один запрос в любое время, а это не то, что вам нужно.

person Rune Grimstad    schedule 12.03.2009

Это зависит от того, какую базу данных или ORM вы используете. Но, судя по моему опыту, это казалось хорошей идеей, но в итоге меня поразило. Вот как это было со мной в LINQ-to-SQL:

У меня был класс репозитория, у которого была статическая переменная для контекста данных. Сначала это сработало, но когда мне пришлось создать гораздо больше классов репозитория, я начал получать ошибки, когда работал. Оказывается, контекст данных в LINQ-to-SQL кэширует все результаты, и нет возможности их обновить. Поэтому, если вы добавили сообщение в таблицу в одном контексте, оно не будет отображаться в другом, который кэшировал эту таблицу. Решением было удалить модификатор static и позволить репозиторию создавать контекст в конструкторе. Поскольку классы репозитория были созданы по мере их использования, то же самое будет и с новым новым контекстом данных.

Вы могли бы возразить, что статические переменные оставляют меньше места в памяти, но след для контекста данных довольно мал для начала и в конце будет собран сборщиком мусора.

person Spoike    schedule 12.03.2009

Вопреки ответу. Я создал веб-фреймворк со статическим доступом к базе данных, он отлично работает и дает отличную производительность.

Вы можете проверить исходный код на странице http://www.codeplex.com/Cubes.

person Emil C    schedule 12.03.2009

Если вы просто выполняете запросы к БД, то да, сделайте его статическим. Вам нужно создать экземпляр только в том случае, если этот объект должен сохранять какое-то состояние.

person Martin Moser    schedule 12.03.2009

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

Итак, что вы, вероятно, захотите сделать, так это иметь статический метод, называемый экземпляром или текущим экземпляром. И внутри вы создаете новый экземпляр вашего db-класса, возвращая его в статическом методе.

person Emil C    schedule 12.03.2009
comment
Держать экземпляры открытыми - не лучшая идея. Вы должны закрыть соединение с БД как можно скорее. - person Inferis; 12.03.2009
comment
Конечно, вы должны закрыть соединение. Но если у вас есть статический класс для доступа к командам, вы можете управлять соединениями с базой данных внутри. Есть команда закрытия ридера после их завершения. - person Emil C; 12.03.2009

Ваши методы подходят для статического использования. Думаю, у вас пока нет проблем с преобразованием их в статические методы.

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

person Canavar    schedule 12.03.2009