C # статический класс базы данных? - PullRequest
6 голосов
/ 12 марта 2009

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

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

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

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

Ответы [ 8 ]

5 голосов
/ 12 марта 2009

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

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

4 голосов
/ 12 марта 2009

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

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

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

2 голосов
/ 12 марта 2009

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

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

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

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

1 голос
/ 12 марта 2009

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

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

1 голос
/ 12 марта 2009

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

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

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

0 голосов
/ 12 марта 2009

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

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

0 голосов
/ 12 марта 2009

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

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

0 голосов
/ 12 марта 2009

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

...