Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

ADO.NET: SQLConnection

1.8K
18 января 2008 года
rSolanov
106 / / 04.05.2005
Здравствуйте. Я хотел бы обсудить одну проблему, которая возникает при написании клиентского приложения с ADO.NET. Я думаю, что большинство, кто начинал писать приложения с использованием данной технологии сталкивался с этой проблемой. В клиентском приложении, которое подключено к БД и получает от туда данные, практически в каждом окне эти данные и отображаются. А значит необходимо постоянно указывать необходимый Connection для получения данных. Поэтому по логике, такой Connection должен быть где-то объявлен глобально. Но .NET не даёт возможности создавать глобальные переменные в рамках всего приложения. Можно если только положть это в класс настроек:
Код:
namespace AppClient.Properties {
   
   
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
       
        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
       
        public static Settings Default {
            get {
                return defaultInstance;
            }
        }
       
        [global::System.Configuration.ApplicationScopedSettingAttribute()]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)]
        [global::System.Configuration.DefaultSettingValueAttribute("Data Source=SERVER-SQL\\SQLSERVER_PIK;Initial Catalog=PIK_Rieltor;Integrated Secur" +
            "ity=True")]
        public string PIK_RieltorConnectionString {
            get {
                return ((string)(this["PIK_RieltorConnectionString"]));
            }
        }
        public global::System.Data.SqlClient.SqlConnection Connection;
    }
}


Но тут есть момент моего непонимания: ведь все эти настройки являются членами класса, посути указатель на объект которого значит где-то должен быть объявлен глобально. Но если посмотреть автоматически сгенерированные участки кода, то можно увидеть, что члены этого класса вызываются не из экземпляра класса, а прямо из него. Но как это? А может Connection лучше хранить не здесь, то где?
Или может я вообще неправильно к этому подхожу?
241
18 января 2008 года
Sanila_san
1.6K / / 07.06.2005
Мы обычно читаем настройки в DataSet из XML, и к нему обращаемся. Довольно удобно, и сделать его глобально видимым несложно. Обычно технология такая: есть некий экзешник, который запускается первым, а остальное подтягивается им в виде библиотек. Вот этот экзешник и читает XML-файл с настройками. В принципе, его может читать вообще кто угодно, лишь бы потом можно было потом передать или DataSet, или через какую-то переменную. Но мы пишем на VB.NET, там просто и тупо объявляется переменная класса. Как в C# сделано, я не знаю, но, в принципе, нечто подобное реально и там. Если невозможно использовать переменную класса, можно объявить DataSet в int Main (){}, будет практически то же самое.

Вообще сейчас припоминаю две идеи доступа к настройкам SqlConnection. Первый - хранить строку подключения как свойство класса, всегда видимого в главном потоке. Второй - создавать SqlConnection и передавать его как параметр нужным функциям. В моём последнем проекте реализованы обе идеи: главный поток читает настройки и передаёт рабочим потокам строку подключения, а те один раз создают подключение к SQL-серверу и потом просто передают его в свои функции как параметр по ссылке. Кажется, не переврал. Сейчас уточню и скажу, как на самом деле.
5
18 января 2008 года
hardcase
4.5K / / 09.08.2005
Что мешает создать класс со статическими членами: например свойством, типа DbConnection, возвращающее экземпляр подключения.
241
21 января 2008 года
Sanila_san
1.6K / / 07.06.2005
Цитата: hardcase
Что мешает создать класс со статическими членами: например свойством, типа DbConnection, возвращающее экземпляр подключения.

Респект. Я предложил то же самое, только долго и непонятно, ну и в терминологии VB.NET. :)

713
21 января 2008 года
Ap0k
360 / / 13.03.2006
Цитата: hardcase
Что мешает создать класс со статическими членами: например свойством, типа DbConnection, возвращающее экземпляр подключения.


+1, а так же: [COLOR=#0000cc]Пространство имён Rsdn.Framework.Data[/COLOR]

241
21 января 2008 года
Sanila_san
1.6K / / 07.06.2005
Цитата: rSolanov
Но .NET не даёт возможности создавать глобальные переменные в рамках всего приложения.

Вообще мне кажется, что это в большой степени заблуждение. Создавать глобальные переменные вообще нехорошая практика, но сделать переменную, видимую глобально, не так уж и сложно, причём способов больше одного. Мы обычно используем передачу объекта (экземпляра класса или его свойства) как параметра по ссылке, можно использовать статические (Shared в VB, static в C#), суть то же самое, отличается в технических деталях. Если речь идёт о параметрах конфигурации, то их можно вообще вынести в XML и читать любым доступным способом в подходящий DataSet, DataTreeView и даже String, короче, так, как лучше всего в данном месте.

1.8K
21 января 2008 года
rSolanov
106 / / 04.05.2005
Ну хорошо, создаю я класс со статическим SQLConnection:
 
Код:
using System.Data.SQLClient;
...
class TOurClass
{
  static SQLConnection Connection;
};

И как я буду создавать Connection не создавая экземпляра класса TOurClass?
1.8K
21 января 2008 года
rSolanov
106 / / 04.05.2005
Товарищи, вы уж помогите пожалуйста...Помогите понять концепцию в целом. Почему же создавать глобальные переменные является плохим тоном программирования? И хорошо, глобальные переменные использовать нельзя, но ведь вы сами говорите что этот принцип можно обойти с помощью статических членов класса. Но если мы сознательно идём в обход принципу, то видимо всеже без глобальных данных (будь то это что угодно, вчастности статический член класса) не обойтись.
А в примере, который написал, ведь Connection необходимо создавать в конструкторе класса TOurClass, а чтобы использовать Connection как глобальную переменную надо вызывать это поле через класс, а не его экземпляр?
241
21 января 2008 года
Sanila_san
1.6K / / 07.06.2005
Цитата: rSolanov
Товарищи, вы уж помогите пожалуйста...Помогите понять концепцию в целом. Почему же создавать глобальные переменные является плохим тоном программирования?


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

Цитата: rSolanov
И хорошо, глобальные переменные использовать нельзя, но ведь вы сами говорите что этот принцип можно обойти с помощью статических членов класса. Но если мы сознательно идём в обход принципу, то видимо всеже без глобальных данных (будь то это что угодно, вчастности статический член класса) не обойтись.

Это нормально, когда имеется некий совместно используемый ресурс. Яркий пример - как раз SQL-подключение, или имя файла настроек, или сокет, или ещё что угодно. Принцип "Не использовать данные, видимые глобально" не существует. Существует принцип "Не использовать глобальные переменные". Просто статическое поле класса уже не глобальная переменная, хотя и может быть использована таким способом.

Цитата: rSolanov
А в примере, который написал, ведь Connection необходимо создавать в конструкторе класса TOurClass, а чтобы использовать Connection как глобальную переменную надо вызывать это поле через класс, а не его экземпляр?

Посмотрите в отладчике, это один из лучших способов понять, как это работает. Вот, что говорит Справка: [QUOTE=MSDN]You access a shared element by qualifying it with its class or structure name, not with the variable name of a specific instance of its class or structure. You do not even have to create an instance of a class or structure to access its shared members.[/QUOTE]

1.8K
21 января 2008 года
rSolanov
106 / / 04.05.2005
Большое вам спасибо за помощь, но остался один невыясненный момент: для использования поля Connection класса TOurClass надо создавать экземпляр класса? А если надо, то где должен находиться указатель на полученный экземпляр класса?
713
21 января 2008 года
Ap0k
360 / / 13.03.2006
1) Экземпляр создавать не нужно
2) Поле Connection класса TOurClass нужно сделать public свойством.
1.8K
21 января 2008 года
rSolanov
106 / / 04.05.2005
Цитата: Ap0k
1) Экземпляр создавать не нужно
2) Поле Connection класса TOurClass нужно сделать public свойством.



Я правильно понимаю:

 
Код:
SQLConnection Connection = new SQLConnection(ConnectionString);
TOurClass.Connection = Connection;

А при вызове пишу:
 
Код:
ExampleObject.MyFunction(TOurClass.Connection);

Так?
241
21 января 2008 года
Sanila_san
1.6K / / 07.06.2005
Цитата: rSolanov
Я правильно понимаю:
 
Код:
SQLConnection Connection = new SQLConnection(ConnectionString);
TOurClass.Connection = Connection;

А при вызове пишу:
 
Код:
ExampleObject.MyFunction(TOurClass.Connection);

Так?

Камрад rSolanov! Не сочтите за сноба, но разве не быстрее проверить в редакторе кода? ;)

Код не проверял, но, кажется, верно. Насчёт вызова не уверен, лучше посмотреть в редакторе.

1.8K
21 января 2008 года
rSolanov
106 / / 04.05.2005
Да, похоже принцип верный. Необходимо использовать понятие синглетона, принцип которого заключается в том, что существует только один экземпляр этого класса, который доступен из любого места программы через статическое свойство. Думаю, что тема раскрыта достаточно. Остальные моменты можно изучить самостоятельно. Спасибо Вам всем огромное за помощь, особенно тов. Sanila_san. Думаю что и посетителям форума, которым потребуется помощь, будут благодарны.
5
24 января 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: rSolanov
Ну хорошо, создаю я класс со статическим SQLConnection:


Код:
public class ConnectionManager {
    private static SqlConnection connection = null;
    public static SqlConnection Connection {
        get {
             if(connection == null) {
                 connection = new SqlConnection("ваша строка соединения, можно считать из конфига");
             }
             return connection;
        }
    }
}
552
24 января 2008 года
Ivanhoe
373 / / 30.04.2006
Цитата: rSolanov
Большое вам спасибо за помощь, но остался один невыясненный момент: для использования поля Connection класса TOurClass надо создавать экземпляр класса? А если надо, то где должен находиться указатель на полученный экземпляр класса?



Скажем так - создавать экземпляр TOurClass не имеет смысла.

 
Код:
using System.Data.SQLClient;
...
class TOurClass
{
  static SqlConnection Connection;
};
...
    TOurClass.Connection = new SqlConnection();
...
552
24 января 2008 года
Ivanhoe
373 / / 30.04.2006
Ну подход товарища hardcase более тру :) Singleton называется :)
1.8K
28 января 2008 года
rSolanov
106 / / 04.05.2005
Тов. hardcase, я так понимаю что экземпляр класса ConnectionManager создавать не надо, а дуступ к connection осуществляется через статическое свойство Connection.
 
Код:
...=ConnectionManager.Connection;

Вы также не могли бы пояснить прицип работы: какже если мы не создавая экземпляра объкта в памяти, не создавая адресное пространство в памяти, не получая указатель на созданный объект, через класс вызываем его методы? Хотелось бы понять в этом случае отношения класс-память и вызов метода класса-память
241
28 января 2008 года
Sanila_san
1.6K / / 07.06.2005
Цитата: rSolanov
Вы также не могли бы пояснить прицип работы: какже если мы не создавая экземпляра объкта в памяти, не создавая адресное пространство в памяти, не получая указатель на созданный объект, через класс вызываем его методы? Хотелось бы понять в этом случае отношения класс-память и вызов метода класса-память

Помните, как учили в советских ВУЗах предметы идеологического направления? Была там знаменитая фраза: "Обращайтесь к первоисточникам:[QUOTE=MSDN]
Shared (Visual Basic)

Specifies that one or more declared programming elements are associated with a class or structure at large, and not with a specific instance of the class or structure.

When to Use Shared

Sharing a member of a class or structure makes it available to every instance, rather than nonshared, where each instance keeps its own copy. This is useful, for example, if the value of a variable applies to the entire application. If you declare that variable to be Shared, then all instances access the same storage location, and if one instance changes the variable's value, all instances access the updated value.

Sharing does not alter the access level of a member. For example, a class member can be shared and private (accessible only from within the class), or nonshared and public.[/QUOTE]Не обращайте внимания на вебедотнет, принцип везде остаётся тот же самый, поскольку на уровне IL различия пропадают. Если жажда исследования одолевает, ILDASM в руки и вперёд - создать класс со статическими переменными и обратиться к ним. Вам наверняка откроется многое, и это полезно для понимания того, что напрямую, впрочем, едва ли удастся использовать. А для решения практических задач достаточно знать, что статическое поле видно отовсюду.;)

1.8K
28 января 2008 года
rSolanov
106 / / 04.05.2005
Sanila_san, пожалуйста, Вы бы не могли написать тоже самое, только по-русски. Дело в том, что по отдельности приблизительно я могу перевести каждое слово, но в целом смысл ухватить полностью, так, как есть, не могу. MSDN я конечно пользуюсь, но при этом когда контекст и смысл темы я знаю, то зная перевод даже отдельных слов, общий смысл понять можно, даже очень точно. Да и не только во мне дело, те, кто будет читать эти посты для своего просвящения, не все хорошо владеют английским языком.
241
28 января 2008 года
Sanila_san
1.6K / / 07.06.2005
Цитата: rSolanov
Sanila_san, пожалуйста, Вы бы не могли написать тоже самое, только по-русски. Дело в том, что по отдельности приблизительно я могу перевести каждое слово, но в целом смысл ухватить полностью, так, как есть, не могу.

Боюсь огорчить, но английский язык в этом деле - lingua franca, и учить его надо любым доступным способом. Точно так же как любой русский дворянин должен был знать французский, хотя, думаю, в принципе прожить мог и без этого. Уж если Дональд Э. Кнут освоил русский в объёме, достаточном для чтения русской математической литературы, то вы, безо всякого сомнения, освоите английский в объёме, достаточном для чтения MSDN без перевода.

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

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

От чтения постов ещё никто, насколько мне известно, святым не стал. ;) О просвещении же говорить несколько наивно, ибо не один раз уже поднималась дискуссия о кризисе этого форума как образовательной сущности. Страждущие же найдут способ понять и английский текст, тем паче, что уже не единожды сказано: английский суть один из пропусков в программирование, полагаю, даже более важный, чем высшая математика.

1.8K
28 января 2008 года
rSolanov
106 / / 04.05.2005
Цитата: Sanila_san
Боюсь огорчить, но английский язык в этом деле - lingua franca, и учить его надо любым доступным способом.
...
От чтения постов ещё никто, насколько мне известно, святым не стал. ;) О просвещении же говорить несколько наивно, ибо не один раз уже поднималась дискуссия о кризисе этого форума как образовательной сущности. Страждущие же найдут способ понять и английский текст, тем паче, что уже не единожды сказано: английский суть один из пропусков в программирование, полагаю, даже более важный, чем высшая математика.


Готов с Вами согласиться.

Цитата: Sanila_san

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


При написании, см. код от тов. hardcase:

 
Код:
...=ConnectionManager.Connection;

Создаётся объект класса SQLConnection c получением на него указателя.
Просто для меня уж очень непривычно видеть обращение к методам через класс, а не через его указатель на экземпляр. Но все же, что при этом с классом ConnectionManager происходит в памяти? Или в памяти отводится адресное пространство только для методов и полей такого класса?
241
28 января 2008 года
Sanila_san
1.6K / / 07.06.2005
Цитата: rSolanov

 
Код:
...=ConnectionManager.Connection;

Создаётся объект класса SQLConnection c получением на него указателя.
Просто для меня уж очень непривычно видеть обращение к методам через класс, а не через его указатель на экземпляр. Но все же, что при этом с классом ConnectionManager происходит в памяти? Или в памяти отводится адресное пространство только для методов и полей такого класса?

Полагаю, тут несколько иначе. Создаётся экземпляр такого класса, а указатели возвращаются с одним и тем же значением. Аналог глобальной переменной, но не простой: он обеспечивает потокобезопасность. Как это сделано - вопрос к копателям внутренностей дотнета, я к ним не отношусь. Если вам интересно, попробуйте дебаггер, он показывает нечто похожее на нужную информацию. Опять же, всё это стоит делать только в том случае, если очень хочется разобраться в указателях. Критической необходимости в этом нет - достаточно вдумчиво читать руководящие документы и писать примеры для проверки всего, что не кажется очевидным. С точки зрения практики это более верный путь. В самом деле, что вам до указателей, если в дотнете их в явном виде нет?

1.8K
28 января 2008 года
rSolanov
106 / / 04.05.2005
Цитата: Sanila_san

Полагаю, тут несколько иначе. Создаётся экземпляр такого класса, а указатели возвращаются с одним и тем же значением.


Да, я так и понял, по приведенному коду от hardcase это очевидно.

Цитата: Sanila_san

В самом деле, что вам до указателей, если в дотнете их в явном виде нет?


Привычка, выработанная годами :-)
Вообще сейчас всё наконец стало совершенно понятно. Спасибо вам всем.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог