Шаг 96.
Microsoft Visual C++ 2010. Начала. Базы данных. Сервер баз данных Microsoft SQL Server Compact 3.5. База данных "Контакты"

    На этом шаге мы рассмотрим пример использования созданной базы.

    Перед тем как приступить к работе над программой, надо создать базу данных (файл mycontacts.mdf) и поместить в нее таблицу contacts (таблица 1).

Таблица 1. Поля таблицы contacts
Поле Тип Примечание
cid INT Автоувеличение
name nvarchar(50) Обязательное поле (Not null)
phone nvarchar(50)  
email nvarchar(50)  

    Форма программы работы с базой данных Microsoft SQL Server Compact 3.5 "Контакты" приведена на рисунке 1.


Рис.1. Форма программы работы с базой данных Microsoft SQL Server Compact 3.5

    Для отображения записей в табличной форме используется компонент ListView (значения его свойств приведены в таблице 2).

Таблица 2. Значения свойств компонента ListView
Свойство Значение
Columns[0].Text cid
Columns[0].Width 35
Columns[1].Text Имя
Columns[1].Width 130
Columns[2].Text Телефон
Columns[2].Width 110
Columns[3].Text E-mail
Columns[3].Width 110
View Detals
HideSelection False
MultiSelect False
GridLines True
FullRowSelect True

    Компоненты textBox1, textBox2 и textBox3 используются для ввода и редактирования полей name, phone и emal, а компонент textBox4 (свойству ReadOnly которого следует присвоить значение True) — для хранения значения поля cid. Нетрудно заметить, что на форме нет компонентов доступа к базе данных. Все необходимые для работы с базой данных объекты создаются "в коде", во время работы программы.

    Доступ к базе данных Microsoft SQL Server Compact 3.5 обеспечивают объекты SqlCeEngine, SqlCeConnection, SqlCeDataAdapter, SqlCeCommand, SqlCeDataReader, которые принадлежат пространству имен System::Data:: SqlServerCe. Чтобы это пространство имен стало доступно, в проект надо добавить ссылку на сборку System.Data.SqlServerCe.dll, в которой оно определено. Для этого надо: в меню Project (Проект) выбрать команду Properties (Свойства); в открывшемся окне Property Page (Страницы свойств) сделать щелчок на кнопке Add New Reference (Добавить новую ссылку); в окне Add Reference (Добавить ссылку) раскрыть вкладку .NET и указать сборку (рисунок 2).


Рис.2. Добавление в проект ссылки на сборку

    При переносе программы на другой компьютер по умолчанию предполагается, что все необходимые для ее работы сборки (библиотеки) на этом компьютере есть. Как правило, это так. Однако если программа использует "нестандартные" библиотеки, сборки, которые по умолчанию в .NET Framework (точнее, в Global Assembly Cache, GAC) не входят, то надо позаботиться об установке на компьютер пользователя необходимых программе сборок. Чтобы подключенная сборка гарантированно была доступна программе при пе-реносе ее на другой компьютер, свойству Copy Local (Копировать локально) надо присвоить значение True (рисунок 3).


Рис.3. Чтобы сборка гарантированно была доступна программе при переносе ее на другой компьютер, свойству Copy Local (Копировать локально) надо присвоить значение True

    В этом случае при построении программы она будет скопирована в каталог выполняемой программы (в зависимости от текущего режима компиляции в папку Debug или Release).

    Если нужная сборка находится не в GAC (имя сборки на вкладке .NET не отображается), то необходимо раскрыть вкладку Browse (Обзор) и указать файл сборки там (в этом случае файл сборки во время компиляции будет скопирован в каталог проекта).

    Приведем текст приложения.

/* 
    Чтобы пространство имен System::Data::SqlServerCe стало доступно, 
    надо в проект добавить ссылку на файл сборки, в котором оно 
    определено. Для этого: в меню Project выбрать команду Properties; 
    в открывшемся окне сделать щелчок на кнопке Add New Reference; 
    раскрыть вкладку .NET и указать имя сборки - System.Data.SqlServerCe. 
*/ 
 
    using namespace System::Data::SqlServerCe; 
    using namespace System::IO;
.   .   .   .
Form1(void)
{
	InitializeComponent();
	//
	//TODO: добавьте код конструктора
	//
	// настройка компонента ListView: 
	// увеличим ширину компонента 
	// на ширину полосы прокрутки 
	int w = 0;
	for (int i = 0; i < listView1->Columns->Count; i++) 
	{
		w += listView1->Columns[i]->Width; 
	}

	if (listView1->BorderStyle == BorderStyle::Fixed3D) 
		w += 4; 
	listView1->Width = w+17; // 17 - ширина полосы прокрутки 
}
.   .   .   .
private: 
    String^ dbf;           // файл БД 
    String^ stDataSource;  // строка вида: DataSource = ФайлБД 
 
// отображает базу данных (таблицу) 
private: void ShowDB()  { 
	 SqlCeEngine^ engine = gcnew SqlCeEngine(stDataSource); 
	 SqlCeConnection^ connection = 
		 gcnew SqlCeConnection(engine->LocalConnectionString); 
connection->Open(); 
SqlCeCommand^ command = connection->CreateCommand(); 
	command->CommandText = "SELECT * FROM contacts ORDER BY name"; 

	 // Выполнить команду. Результат находится в DataReader 
             SqlCeDataReader^ dataReader = command->ExecuteReader(); 

	 String^ st;  // значение поля БД 
	 int itemIndex = 0; 

	 listView1->Items->Clear(); 

	 while (dataReader->Read()) 
	 {
		 for (int i = 0; i < dataReader->FieldCount; i++) 
		 {
			 st = dataReader->GetValue(i)->ToString(); 
			 switch (i) 
			 {
			    case 0:  // поле cid 
			   	 listView1->Items->Add(st); 
				 break; 
			    case 1:  // поле name 
				 listView1->Items[itemIndex]->SubItems->Add(st); 
				 break; 
			    case 2:  // поле phone 
				 listView1->Items[itemIndex]->SubItems->Add(st); 
				 break; 
			    case 3:  // поле email 
				 listView1->Items[itemIndex]->SubItems->Add(st); 
				 break;
			 }
		 }
		 itemIndex++; 
	 }
	 connection->Close(); 
} 
// начало работы программы - загрузка формы 
private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
	 SqlCeEngine^ engine; // процессор БД 
 
	// предполагается, что файл БД находится в той же 
	// папке, что и exe-файл 
	String^ dbf = Application::StartupPath + "\\contacts.sdf"; 
 
	stDataSource = "Data Source='" + dbf + "';"; 

	engine = gcnew SqlCeEngine(stDataSource); 
 
	// проверим, доступен ли файл БД 
	if (!(File::Exists(dbf))) 
	{ 
		// Создать БД SQL Server Compact Edition. 
		// БД будет создана в каталоге приложения. 
		// При запуске программы из среды разработки 
		// БД будет создана в каталоге Debug или Release 
		engine->CreateDatabase(); 
		SqlCeConnection^ connection = 
			gcnew SqlCeConnection(engine->LocalConnectionString); 
		connection->Open(); 
		SqlCeCommand^ command = connection->CreateCommand(); 
		command->CommandText = 
			"CREATE TABLE contacts (cid int IDENTITY(1,1)," 
			"name nvarchar(50) NOT NULL, phone nvarchar(50)," 
			"email nvarchar(50))"; 
		command->ExecuteScalar(); 
		connection->Close(); 
	}
	else 
	{ 
		ShowDB(); 
	} 
 }
// щелчок на кнопке Добавить 
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
	 SqlCeConnection^ conn = 
		 gcnew SqlCeConnection(stDataSource); 
	 conn->Open();
	 SqlCeCommand^ command = conn->CreateCommand(); 
	 command->CommandText = 
		 "INSERT INTO contacts(name, phone,email) VALUES(?,?,?)"; 
		 command->Parameters->Add("name", textBox1->Text); 
	 command->Parameters->Add("phone", textBox2->Text); 
	 command->Parameters->Add("email", textBox3->Text); 
	 command->ExecuteScalar(); 
	 conn->Close(); 
 
	 // очистить поля ввода 
	 textBox1->Clear(); 
	 textBox2->Clear(); 
	 textBox3->Clear(); 
 
	 ShowDB(); 
 
	 // установить курсор в поле textBox1 
	 textBox1->Focus(); 
 }
// щелчок на кнопке Найти 
private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) {
	 SqlCeEngine^ engine = gcnew SqlCeEngine(stDataSource); 
	 SqlCeConnection^ connection = 
		 gcnew SqlCeConnection(engine->LocalConnectionString); 
	 connection->Open(); 
 
	 SqlCeCommand^ command = connection->CreateCommand(); 
 
	 command->CommandText = 
		 "SELECT * FROM contacts WHERE (name LIKE ?)"; 
	 command->Parameters->Add("name", "%" + textBox1->Text + "%"); 
 
	 SqlCeDataReader^ dataReader = command->ExecuteReader(); 
 
	 String^ st;  // значение поля БД 
	 int itemIndex = 0; 
 
	 listView1->Items->Clear(); 
 
	 while (dataReader->Read()) 
	 { 
		 for (int i = 0; i < dataReader->FieldCount; i++)   { 
			 st = dataReader->GetValue(i)->ToString(); 
			 switch (i)
			 { 
			   case 0:  // поле cid 
				 listView1->Items->Add(st); 
				 break; 
			   case 1:  // поле name 
				 listView1->Items[itemIndex]->SubItems->Add(st); 
				 break; 
			   case 2:  // поле phone 
				 listView1->Items[itemIndex]->SubItems->Add(st); 
				 break; 
			   case 3:  // поле email 
				 listView1->Items[itemIndex]->SubItems->Add(st); 
				 break; 
			 } 
		 } 
		 itemIndex++; 
	 } 
	 connection->Close(); 
}
// в поле компонента listView пользователь выбрал другую строку
private: System::Void listView1_ItemSelectionChanged(System::Object^  sender, 
         System::Windows::Forms::ListViewItemSelectionChangedEventArgs^  e) {
	 /* 
		При выборе строки событие ItemSelectionChanged 
		возникает два раза: первый раз, когда выделенная в 
		данный момент строка теряет фокус, второй - когда 
		строка, в которой сделан щелчок, получает фокус. 
		Нас интересует строка, которая получает фокус. 
	*/
	 if (e->IsSelected) 
	 { 
		 // строка выбрана, т. е. она получила фокус 
		 textBox4->Text = listView1->Items[e->ItemIndex]->Text; 
 
		 // Продублируем содержимое полей текущей 
		 // записи в поля textBox 
		 for (int i = 1; 
			 i < listView1->Items[e->ItemIndex]->SubItems->Count; 
			 i++)  { 
				 switch (i) 
				 {
	 			  case 1: 
				   textBox1->Text = 
				    listView1->Items[e->ItemIndex]->SubItems[i]->Text; 
				   break; 
				  case 2: 
				   textBox2->Text = 
				    listView1->Items[e->ItemIndex]->SubItems[i]->Text; 
				   break; 
				  case 3: 
				   textBox3->Text = 
				    listView1->Items[e->ItemIndex]->SubItems[i]->Text; 
				   break; 
				 } 
		 } 
	 }
 }
// щелчок на кнопке Удалить
private: System::Void button4_Click(System::Object^  sender, System::EventArgs^  e) {
	 if (listView1->SelectedItems->Count != 0) 
	 { 
		 SqlCeEngine^ engine = gcnew SqlCeEngine(stDataSource); 
 
		 SqlCeConnection^ connection = 
		 	 gcnew SqlCeConnection(engine->LocalConnectionString); 
 
		 connection->Open(); 
 
		 SqlCeCommand^ command = connection->CreateCommand(); 
 
		 command->CommandText = "DELETE FROM contacts WHERE (cid = ?)"; 
      
		 command->Parameters->Add("cid", textBox4->Text); 
 
		 command->ExecuteScalar(); // выполнить команду 
 
		 ShowDB(); 
		 textBox1->Clear(); 
		 textBox2->Clear();   
		 textBox3->Clear(); 
		 textBox4->Clear(); 
	 } 
 }
// щелчок на кнопке Изменить 
private: System::Void button3_Click(System::Object^  sender, System::EventArgs^  e) {
	 if (listView1->SelectedItems->Count != 0) 
	 {
		 SqlCeEngine^ engine = gcnew SqlCeEngine(stDataSource); 
 
		 SqlCeConnection^ connection = gcnew 
				 SqlCeConnection(engine->LocalConnectionString); 
 
		 connection->Open(); 
 
		 SqlCeCommand^ command = connection->CreateCommand(); 
 
		 command->CommandText = "UPDATE contacts " + 
			 "SET name = ?, phone =?, email=? " + 
			 "WHERE cid = ?"; 
 
		 command->Parameters->Add("name", textBox1->Text); 
		 command->Parameters->Add("phone", textBox2->Text); 
		 command->Parameters->Add("email", textBox3->Text); 
		 command->Parameters->Add("cid", textBox4->Text); 
 
		command->ExecuteScalar(); // выполнить команду 
 
		 ShowDB(); 
 
		 textBox1->Clear(); 
		 textBox2->Clear(); 
		 textBox3->Clear(); 
		 textBox4->Clear(); 
	 } 
 }
// Обработка события TextChanged компонентов textBox1-textBox3. 
// Одна функция обрабатывает событие от трех компонентов. 
private: System::Void textBox_TextChanged(System::Object^ sender, 
             System::EventArgs^  e)  { 
	 // Кнопка Добавить становится доступной, 
	 //  если информация введена в поле Имя 
	 //  и в какое-либо из полей - Телефон или E-mail 
	 if ((textBox1->TextLength > 0) && 
		 ((textBox2->TextLength > 0) || 
		 (textBox3->TextLength > 0))) 
		 button1->Enabled = true; 
	 else 
	 { 
		 button1->Enabled = false; 
	 } 
}  

Архив проекта вместе с базой данных можно взять здесь.

    На следующем шаге мы рассмотрим развертывание приложения.




Предыдущий шаг Содержание Следующий шаг