Бд sql и пользовательское приложение c# турфирмы. Создание базы данных

класс SqlConnection , а за связь с базой данных Access - OleDbConnection. Первый является частью провайдера данных SQLDataProvider, второй - провайдера данных OLEDbProvider.

Программный код меняется в зависимости от того, с какой базой предстоит работать. Для демонстрации возможностей использования баз данных , работающих под управлением различных СУБД , мы создали базу данных Planets в Microsoft SQL Server и в Access. Поскольку формат базы данных в Access 2007 отличается от формата, принятого в предыдущих версиях, реализация выполнена для версий Access 2007 и Access 2003. Естественно, что все особенности построения баз данных находят отражение в программном коде.

Три варианта базы данных Planets помещены в каталог с именем databases. Файлы Planets.mdf и Planets.ldf, задают базу данных SQL Server , файл Planets.accdb создан для базы данных Access 2007, а Planets. mdb - для базы данных Access 2003.

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

При работе с базой данных SQL Server программный код зависит от того, с какой версией СУБД приходится работать - с Microsoft SQL Server или Microsoft SQL Server Express Edition .

В приведенном ниже примере показаны четыре возможных варианта работы:

  1. работа с Microsoft SQL Server Express Edition;
  2. работа с Microsoft SQL Server;
  3. работа с Access 2003;
  4. работа с Access 2007.

Три варианта закомментированы, а один готов к использованию, в данном тексте это вариант работы с Microsoft SQL Server . В зависимости от того, что установлено на компьютере читателя, следует нужный вариант раскомментировать, а ненужный - закомментировать.

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

Когда вам понадобятся более широкие возможности программирования, мы рекомендуем вам установить SQL Server Express. К тому же умение работать с SQL Server гораздо выше ценится в деловой сфере, и чем скорее вы освоите этот инструмент, тем лучше. Загрузить его можно бесплатно с сайта Microsoft: http://www.microsoft.com/ .

Обращение к базам данных из программы, написанной на языке C#

Далее в трех примерах программ на C# мы будем использовать классы Connection , Command , DataReader , DataAdapter . Префиксы Sql и OleDb указывают на то, с каким вариантом базы данных Planets мы работаем.

Пример программы 4.1

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

Using System.Windows.Forms; using System.Data; // Пространство имен для работы с базами данных SQL Server using System.Data.SqlClient; using System.Drawing; // Пространство имен для работы с базами данных Access using System.Data.OleDb; class SimpleDataAccess: Form { public SimpleDataAccess() { // Указываем заголовок окна this.Text = "Работа с базой данных. Чтение данных."; // Добавляем элементы управления - метку и список Label labelCaption = new Label(); labelCaption.Text = "Планеты солнечной системы!"; labelCaption.Location = new Point(30, 10); labelCaption.Width = 200; labelCaption.Parent = this; ListBox listPlanets = new ListBox(); listPlanets.Location = new Point(30, 50); listPlanets.Width = 100; listPlanets.Parent = this; // Формируем запрос к базе данных - //запрашиваем информацию о планетах string sql = "SELECT * FROM PLANET"; string connectionString; /* //Вариант 1 // Подключаемся к базе данных SQL Server Express Edition // Указываем физический путь к базе данных PLANETS string dbLocation = ("../../../databases/planets.mdf"); connectionString = @"data source=.\SQLEXPRESS;" + "User Instance=true;Integrated Security=SSPI;" + "AttachDBFilename=" + dbLocation; SqlConnection connection1 = new SqlConnection(connectionString); */ //Вариант 2 // Подключаемся к базе данных SQL Server 2005 connectionString = "data source = localhost; Initial Catalog = Planets;" + "Integrated Security = SSPI"; SqlConnection connection1 = new SqlConnection(connectionString); //Открываем соединение connection1.Open(); SqlCommand command1 = new SqlCommand(sql, connection1); SqlDataReader dataReader1 = command1.ExecuteReader(); // Организуем циклический перебор полученных записей //и выводим название каждой планеты в список while (dataReader1.Read()) { listPlanets.Items.Add(dataReader1["PlanetName"]); } // Очистка dataReader1.Close(); connection1.Close(); /* //Вариант 3. Связывание с базой данных Access 2003 - *.mdb connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + @"Data Source= ../../../databases/planets.mdb"; //Вариант 4. Связывание с базой данных Access 2007 - *.accdb connectionString = "Provider=Microsoft.Ace.OLEDB.12.0;" + @"Data Source= ../../../databases/planets.accdb"; OleDbConnection connection = new OleDbConnection(connectionString); connection.Open(); OleDbCommand command = new OleDbCommand(sql, connection); OleDbDataReader dataReader = command.ExecuteReader(); // Организуем циклический перебор полученных записей //и выводим название каждой планеты в список while (dataReader.Read()) { listPlanets.Items.Add(dataReader["PlanetName"]); } // Очистка dataReader.Close(); connection.Close(); * */ } static void Main() { // Создаем и запускаем форму Application.Run(new SimpleDataAccess()); } } Листинг 4.1.

Пример программы 4.2

В этой программе на экран выводится несколько столбцов данных. Для их представления мы воспользуемся элементом DataGridView .

Программа выполняет тот же запрос , что и в предыдущем примере, но помещает результат в объект DataSet , который подключается к элементу управления DataGridView , а тот автоматически отображает все данные.

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

Using System.Windows.Forms; using System.Data; // Пространство имен для работы с базами данных SQL Server using System.Data.SqlClient; using System.Drawing; // Пространство имен для работы с базами данных Access using System.Data.OleDb; class DataInGrid: Form { public DataInGrid() { //Изменяем размеры формы this.Width = 450; this.Height = 400; // Указываем заголовок окна this.Text = "Одностороннее связывание:" + " база данных и элемент Grid."; // Добавляем элементы управления - метку и таблицу Label labelCaption = new Label(); labelCaption.Text = "Планеты солнечной системы!"; labelCaption.Location = new Point(60, 10); labelCaption.Width = 200; labelCaption.Parent = this; // Добавляем элемент DataGridView на форму DataGridView dataGridView1 = new DataGridView(); dataGridView1.Width = 350; dataGridView1.Height = 250; dataGridView1.Location = new Point(20, 50); dataGridView1.DataMember = "Table"; dataGridView1.AutoResizeColumns(); this.Controls.Add(dataGridView1); // Формируем запрос к базе данных - //запрашиваем информацию о планетах string sql = "SELECT * FROM PLANET"; string connectionString; // DataSet сохраняет данные в памяти //данные хранятся в виде таблиц данных DataTable DataSet dataSet1 = new DataSet(); /* //Вариант 1 // Подключаемся к базе данных SQL Server Express Edition // Указываем физический путь к базе данных PLANETS string dbLocation = ("../../../databases/planets.mdf"); connectionString = @"data source=.\SQLEXPRESS;" + "User Instance=true;Integrated Security=SSPI;" + "AttachDBFilename=" + dbLocation; SqlConnection connection1 = new SqlConnection(connectionString); */ /* //Вариант 2 // Подключаемся к базе данных SQL Server 2005 connectionString = "data source = localhost; Initial Catalog = Planets;" + "Integrated Security = SSPI"; SqlConnection connection1 = new SqlConnection(connectionString); //Открываем соединение connection1.Open(); // DataAdapter - посредник между базой данных и DataSet SqlDataAdapter sqlDataAdapter1 = new SqlDataAdapter(); // Создаем объект DataAdapter, //передаем ему данные запроса sqlDataAdapter1.SelectCommand = new SqlCommand(sql, connection1); // Данные из адаптера поступают в DataSet sqlDataAdapter1.Fill(dataSet1); // Связываем данные с элементом DataGridView DataGridView1.DataSource = dataSet1; // Очистка connection1.Close(); * */ /* //Вариант 3. Связывание с базой данных Access 2003 - *.mdb connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + @"Data Source= ../../../databases/planets.mdb"; */ //Вариант 4. Связывание с базой данных Access 2007 - *.accdb connectionString = "Provider=Microsoft.Ace.OLEDB.12.0;" + @"Data Source= ../../../databases/planets.accdb"; OleDbConnection connection = new OleDbConnection(connectionString); connection.Open(); OleDbDataAdapter dataAdapter = new OleDbDataAdapter(); dataAdapter.SelectCommand = new OleDbCommand(sql, connection); dataAdapter.Fill(dataSet1); dataGridView1.DataSource = dataSet1; // Очистка connection.Close(); } static void Main() { // Создаем и запускаем форму Application.Run(new DataInGrid()); } } Листинг 4.2.

  • Tutorial

Цель урока : Изучить основные принципы работы с базой данных. Краткое описание реляционной модели баз данных. Работа с базой данных (создание таблиц, связей в VS 2012). Команды INSERT, UPDATE, DELETE, SELECT. Использование LinqToSql и Linq. Создание репозитария, IRepository, SqlRepository.

Что такое БД
Реляционная база данных - база данных, основанная на реляционной модели данных. Реляционность – это отношения (связи) от англ. relation.
Таблицы
Это таблица:

Таблица состоит из столбцов и строк. Столбцы имеют свойства – имя, тип данных.
Таблицы должны обладать следующими свойствами:

  • у таблицы есть имя (уникальное)
  • нет двух одинаковых строк
  • столбцы имеют разные наименования (нет двух одинаковых столбцов)
  • порядок строк в таблице произвольный (т.е. не надо учитывать порядок строк, если не задана сортировка)
Структуру таблицы можно записать в таком виде:
  • Имя столбца
  • Тип данных для этого столбца
Связи
Между таблицами существуют связи (relation). Для установки связи необходимо иметь следующее:
  • Первичный ключ – это набор столбцов (атрибутов) таблицы, однозначно определяющих уникальность строки. Обычно это одно поле, называется ID. Оно является автоикрементным, т.е. при попытке добавления записи, там автоматически вставляется 1, 2, 3, 4… n+1, где n – это значение последнего добавленного ID.
  • Внешний ключ – это набор столбцов (атрибутов) таблицы, которые однозначно определяют уникальность строки в другой таблице. Опять же это обычно одно поле, названное [Имя таблицы]ID. Но не является автоинкрементным.
  • Прописана связь между первичным ключом и внешним ключом.

Связи бывают трех типов:

  • Один-к-одному. Т.е. одной строке в таблице соответствует одна строка в другой таблице. Это редко используется, но используется. Например, в одной таблице данные о пользователе, а в другой - дополнительные данные о том же пользователе. Такой вариант необходим, чтобы манипулировать, по необходимости, меньшим количеством данных.
  • Один-ко-многим. Одной строк в таблице A соответствует одна или несколько строк в таблице B. Но одной строке в таблице B соответствует только одна строка в таблице A. В этом случае в таблице B существует внешний ключ, который однозначно определяет запись в таблице A.
  • Многие-ко-многим. Одной строке в таблице А соответствует одна или несколько строк в таблице В, что истинно и в обратном. В данном случае создается дополнительная таблица со своим первичным ключом, и двумя внешними ключами к таблице A и B.
Сейчас разберемся, как это делать.
Создание простой схемы в БД
Создадим БД в VS 2012:


Назовем её LessonProject, и добавим 3 таблицы Role User и UserRole.
Создадим таблицу Role:



Для строковых значений используем тип nvarchar(n), где n – максимальная длина строки, обычно используется от 50 до 500. Для больших текстовых строк используется nvarchar(MAX).

Устанавливаем первичный ключ:


Задаем для ID автоинкремент:


Подобным образом создаем таблицу User:

Создаем таблицу UserRole:

Добавим связи:


Добавляем новую связь, нажав Add. Добавление связей происходит в таблице, где находятся внешние ключи. Раскрываем вкладку Tables and Columns и выставляем таблицу с первичным ключом, и выбираем внешний ключ в текущей таблице UserRole.


В свойствах INSERT And UPDATE Specification выставляем On Update/On Delete свойства Cascade:


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

Аналогичную связь мы устанавливаем с таблицей User.

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

SELECT, INSERT, UPDATE, DELETE.
В реляционных базах данных используется язык запросов SQL.

Есть 4 основные команды для манипулирования данными - SELECT, INSERT, UPDATE, DELETE

SELECT – для выбора данных и таблиц.
Пример:
SELECT * FROM User
INSERT - Добавление строк в таблицу
Пример:
INSERT INTO Role (Code, Name) VALUES (“admin”, “Администратор”)
UPDATE – изменение значений в таблице
Пример:
UPDATE User SET Password=”password1” WHERE ID=1
DELETE – удаление строк из таблицы
Пример:
DELETE FROM User WHERE ID =1

Примечание: Подробнее можно изучить SQL по ссылкам:
http://www.w3schools.com/sql/
http://codingcraft.ru/sql_queries.php

LinqToSQL и Linq.
Создадим проект LessonProject.Model для работы с БД типа ClassLibrary.
Добавляем LINQ to SQL Classes тип, называем LessonProejctDb.dbml


Открываем объект, выделяем все таблицы и мышкой переносим на холст:


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

  • классы, готовые к использованию в работе с БД
  • визуальное отображение таблиц и связей

Добавим несколько данных в таблицу Role и User:

1 admin Админ
2 customer Заказчик
1 [email protected] 123456 1/1/2012 12:00:00 AM NULL 123456 NULL NULL
2 [email protected] 123456 1/1/2012 12:00:00 AM NULL 123456 NULL NULL
ID UserID RoleID
1 1 1
2 1 2
3 2 2

Создадим консольный проект Lesson3 и подключим LessonProject.Model. Добавим сборку System.Configuration и System.Data.Linq. Проинициализируем context и выведем данные о ролях:
class Program { static void Main(string args) { var context = new LessonProjectDbDataContext(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); var roles = context.Roles.ToList(); foreach (var role in roles) { Console.WriteLine("{0} {1} {2}", role.ID, role.Code, role.Name); } Console.ReadLine(); } }

Для добавления строки в Role делаем так:
var newRole = new Role { Code = "manager", Name = "Менеджер" }; context.Roles.InsertOnSubmit(newRole); context.Roles.Context.SubmitChanges();
Для удаления строки в Role делаем так:
var role = context.Roles.Where(p => p.Name == "Менеджер").FirstOrDefault(); if (role != null) { context.Roles.DeleteOnSubmit(role); context.Roles.Context.SubmitChanges(); }
Для изменения данных делаем так:
var role = context.Roles.Where(p => p.Name == "Менеджер").FirstOrDefault(); if (role != null) { role.Name = "Манагер"; context.Roles.Context.SubmitChanges(); }
Для манипуляции данных используется язык запросов Linq. Мы рассмотрим только некоторые основные функции Linq. Linq применяется для типов реализующий интерфейс IQueryable<>

  • .Where() – основная функция фильтрации. Возвращает тип IQueryable. Условие внутри должно возвращать булево значение (bool).
    var roles = context.Roles.Where(p => p.Name == "Менеджер")
  • .FirstOrDefault() - .First(), .Single(), .SingleOrDefault() – получают первую или единственную запись. Если записи нет, то FirstOrDefault() или SingleOrDefault() возвращают null (на самом деле, значение по умолчанию этого типа , например).
    var roles = context.Roles.Where(p => p.Name == "Менеджер").FirstOrDefault() – получаем первую (или не получаем) роль названную «Менеджер».
  • .Take() – выбирает N первых записей
    var roles = context.Roles.Where(p => p.Name == "Менеджер").Take(4) – выберет 4 первые записи
  • .Skip() – пропускает выбор N первых записей
    var roles = context.Roles.Where(p => p.Name == "Менеджер"). Skip(2).Take(3) – пропустит первые 2 и выберет 3 следующие записи
  • .OrderBy() – сортирует по возрастанию. А также OrderByDescending(), ThenBy(), ThenByDescending(). Лямбда-выражение должно возвращать тип int, по которому и будет происходить сортировка.
    var roles = context.Roles.Where(p => p.Name == "Менеджер").OrderBy(p => p.ID) – сортирует по порядку
  • .Count() – получает количество записей
    var rolesCount = context.Roles.Where(p => p.Name == "Менеджер").Count() – количество записей
  • .Any() – существует одна или больше записей по данному условию
    var rolesExist = context.Roles.Where(p => p.Name == «Менеджер»).Any() – есть ли запись такая
  • . Select() – возвращает IQueryable произвольного типа, может быть даже dynamic:
    var otherRole = context.Roles.Where(p => p.Name == "Менеджер").Select(p => new { ID = p.ID, Kod = p.Code}) – получаем динамический тип, сформированный на основе Role.
  • .SelectMany() – возвращает объединение всех IQueryable типов внутри выборки:
    var otherRole = context.Roles.Where(p => p.Name == "Менеджер").SelectMany(p => p.UserRoles) – получаем все UserRole из роли, названной «Менеджер»
  • .Distinct() – удаляет дубликаты
    var managers = context.Roles.Where(p => p.Name == "Менеджер").SelectMany(p => p.UserRoles).Select(p => p.User).Distinct() – все пользователи с ролью названной «Менеджер»
Примечание: First(), FirstOrDefault(), Single(), SingleOrDefault(), Any(), Count() – могут применять параметр, соответствующий Where() , тем самым, можно сокращать запись:
var roles = context.Roles.FirstOrDefault(p => p.Name == "Менеджер")

Больше примеров и вариантов использования linq вы сможете найти:
http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

Создание репозитория IRepository, SqlRepository.

Собственно с БД мы уже можем работать, только теперь нужно отделить модель данных от конкретной реализации, т.е. наши контроллеры про context и System.Data.Linq вообще не должны ничего знать.

Для этого создадим интерфейс IRepository, где будет дан доступ к данным, а также выведены методы для создания, изменения и удаления этих данных.
public interface IRepository { IQueryable Roles { get; } bool CreateRole(Role instance); bool UpdateRole(Role instance); bool RemoveRole(int idRole); … }

Реализацию назовем SqlRepository. Так как мы с данным контекстом SqlRepository не хотим особо связывать, то добавим Ninject модуль в проект LessonProject.Model:
Install-Package Ninject

Создадим класс SqlRepository:

Public class SqlRepository: IRepository { public LessonProjectDbDataContext Db { get; set; } public IQueryable Roles { get { throw new NotImplementedException(); } } public bool CreateRole(Role instance) { throw new NotImplementedException(); } public bool UpdateRole(Role instance) { throw new NotImplementedException(); } public bool RemoveRole(int idRole) { throw new NotImplementedException(); } }

Прежде, чем реализовать доступ ко всем таблицам, создание, удаление и изменение, подумаем о том, что файл этот будет выглядеть громадным и неуклюжим. Таким кодом будет управлять тяжело физически. Так что сделаем отдельную папку SqlRepository и SqlRepository класс сделаем partial, а в папке создадим реализации интерфейса IRepository, разбитые по каждой таблице. Назовем файл Role:

Public partial class SqlRepository { public IQueryable Roles { get { return Db.Roles; } } public bool CreateRole(Role instance) { if (instance.ID == 0) { Db.Roles.InsertOnSubmit(instance); Db.Roles.Context.SubmitChanges(); return true; } return false; } public bool RemoveRole(int idRole) { Role instance = Db.Roles.FirstOrDefault(p => p.ID == idRole); if (instance != null) { Db.Roles.DeleteOnSubmit(instance); Db.Roles.Context.SubmitChanges(); return true; } return false; } }

Небольшой проект содержит от 10 до 40 таблиц, большой проект от 40, и всё это хотелось бы как-то автоматизировать. Создадим несколько сниппетов, для IRepository и для SqlRepository. Сниппеты – это уже готовые шаблоны кода, которые вызываются с помощью intelliSence, и позволяют быстро создавать код.

Сниппеты

Для IRepository таблиц, создадим table.snippet:

Table Table
Table Table name for create. Table

Для SqlRepository создадим сниппет sqlTable.snippet:

Sql repository sqltable
Table Table name for create. Table
Для того, чтобы добавить code-snippet. откроем TOOLS -> Code Snippet Manager… (Ctrl-K, B). В окне нажимаем Import и импортируем оба сниппета в My Code snippet:


Finish, OK.
Используем для таблиц User и UserRole.


Осталось прописать только поля для Update [имя таблицы], но это уже меньше работы.

Proxy
Как видим, классы, которые мы используем, являются partial, поэтому их можно дополнить. Создадим, подобно SqlRepository, папку Proxy, где будем размещать partial классы. Например, для класса User создадим метод, который автоматически генерирует строку, требуемую для активации пользователя:
public partial class User { public static string GetActivateUrl() { return Guid.NewGuid().ToString("N"); } }
Используем это:
public bool CreateUser(User instance) { if (instance.ID == 0) { instance.AddedDate = DateTime.Now; instance.ActivatedLink = User.GetActivateUrl(); Db.Users.InsertOnSubmit(instance); Db.Users.Context.SubmitChanges(); return true; } return false; }
Использование БД в asp.net mvc
Добавим строку доступа к БД в web.Config:

Проинициализируем работу с БД в Ninject:
private static void RegisterServices(IKernel kernel) { kernel.Bind().ToMethod(c => new LessonProjectDbDataContext(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString)); kernel.Bind().To().InRequestScope(); }
Применяем InRequestScope(). Т.е. каждый запрос будет использовать отдельный объект SqlRepository. Это позволит избежать коллизий при исполнении.Объявляем IRepository в контроллере:
public class HomeController: Controller { public IRepository Repository { get; set; } public ActionResult Index() { var roles = Repository.Roles.ToList(); return View(roles); } }

И обновляем View (/Views/Home/Index.cshtml):
@model IList @{ ViewBag.Title = "LessonProject"; Layout = "~/Views/Shared/_Layout.cshtml"; }

LessonProject

@foreach (var role in Model) {

@role.ID @role.Name @role.Code
}

Получаем хороший результат:


Все исходники находятся по адресу

Создание базы данных

Ниже мы будем выполнять запросы к простой тестовой базе данных SQL Server с именем AutoLot. Эта база данных будет содержать три взаимосвязанных таблицы (Inventory, Orders и Customers), содержащих различные данные о заказах гипотетической компании по продаже автомобилей.

Ниже предполагается, что у вас имеется копия Microsoft SQL Server (7.0 или выше) или копия Microsoft SQL Server 2008 Express Edition . Этот облегченный сервер баз данных отлично подходит для наших потребностей: он бесплатен, предоставляет графический интерфейс (SQL Server Management Tool) для создания и администрирования баз данных и интегрирован с Visual Studio 2010/Visual C# 2010 Express Edition.

Для демонстрации последнего пункта остаток этого раздела будет посвящен созданию базы данных AutoLot с помощью Visual Studio 2010. Если вы пользуетесь Visual C# Express, то сможете выполнить аналогичные действия в окне проводника баз данных (Database Explorer, открывается с помощью пункта меню View --> Other Windows (Вид --> Другие окна)).

Создание таблицы inventory

Чтобы приступить к созданию тестовой базы данных, запустите Visual Studio 2010 и откройте Server Explorer через меню View (Просмотр). Затем щелкните правой кнопкой мыши на узле Data Connections (Подключения к данным) и выберите в контекстном меню пункт Create New SQL Server Database (Создать новую базу данных SQL Server). В открывшемся диалоговом окне подключитесь к SQL Server, установленному на вашей локальной машине (с именем (local)), и укажите в поле имени базы данных AutoLot. Для наших целей можно оставить аутентификацию Windows:

Сейчас база данных AutoLot совершенно пуста и не содержит никаких объектов (таблиц, хранимых процедур и т.п.). Для добавления новой таблицы щелкните правой кнопкой мыши на узле Tables (Таблицы) и выберите в контекстном меню пункт Add New Table:


С помощью редактора таблиц добавьте в таблицу четыре столбца данных: CarID (Идентификатор автомобиля), Make (Модель), Color (Цвет) и PetName (Дружественное имя). У столбца CarID должно быть установлено свойство Primary Key (первичный ключ) - для этого щелкните правой кнопкой мыши на строке CarID и выберите в контекстном меню пункт Set Primary Key (Установить первичный ключ). Окончательные параметры таблицы показаны на рисунке ниже. На панели Column Properties (Свойства столбца) ничего делать не надо, просто запомните типы данных для каждого столбца:


Сохраните и закройте новую таблицу; новый объект базы данных должен иметь имя Inventory. Теперь таблица Inventory должна быть видна под узлом Tables (Таблицы) в Server Explorer. Щелкните правой кнопкой мыши на ее значке и выберите в контекстном меню пункт Show Table Data (Просмотр данных таблицы). Введите информацию о нескольких новых автомобилях по своему усмотрению (чтобы было интереснее, пусть у некоторых автомобилей совпадают цвета и модели). Один из возможных вариантов списка товаров приведен на рисунке:


Создание хранимой процедуры GetPetName()

В последующих статьях будет показано, как вызывать хранимые процедуры в ADO.NET. Возможно, вы уже знаете, что хранимые процедуры - это подпрограммы, хранимые непосредственно в базе данных; обычно они работают с данными таблиц и возвращают какое-то значение. Мы добавим в базу данных одну хранимую процедуру, которая по идентификатору автомобиля будет возвращать его дружественное имя. Для этого щелкните правой кнопкой мыши на узле Stored Procedures (Хранимые процедуры) базы данных AutoLot в Server Explorer и выберите в контекстном меню пункт Add New Stored Procedure (Добавить новую хранимую процедуру). В появившемся окне редактора введите следующий текст:

При сохранении, этой процедуре автоматически будет присвоено имя GetPetName, взятое из оператора CREATE PROCEDURE (учтите, что при первом сохранении Visual Studio 2010 автоматически изменяет имя SQL-сценария на "ALTER PROCEDURE..."). После этого новая хранимая процедура будет видна в Server Explorer:

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

Создание таблиц Customers и Orders

В нашей тестовой базе данных должны быть еще две таблицы: Customers (Клиенты) и Orders (Заказы). Таблица Customers будет содержать список клиентов и состоять из трех столбцов: CustID (Идентификатор клиента; должен быть первичным ключом), FirstName (Имя) и LastName (Фамилия). Повторите шаги, которые были выполнены для создания таблицы Inventory, и создайте таблицу Customers, пользуясь схемой, приведенной на рисунке:


После сохранения этой таблицы добавьте в нее несколько записей:

Последняя наша таблица - Orders - предназначена для связи клиентов и интересующих их автомобилей. Для этого выполняется отображение значений OrderID на CarID/CustID. Ее структура показана ниже (здесь OrderID также является первичным ключом):

Теперь добавьте в таблицу Orders данные. Выберите для каждого значения CustID уникальное значение CarID (предположим, что значения OrderID начинаются с 1000):

Например, в соответствии с информацией, приведенной на рисунках, видно, что Дэйв Бреннер (Dave Brenner, CustID = 1) мечтает о черном BMW (CarID = 1000), а Пэт Уолтон (Pat Walton, CustID = 4) приглянулся розовый Saab (CarID = 1992).

Визуальное создание отношений между таблицами

И, наконец, между таблицами Customers, Orders и Inventory нужно установить отношения "родительский-дочерний". В Visual Studio 2010 это выполняется очень просто, т.к. она позволяет вставить новую диаграмму базы данных на этапе проектирования. Для этого откройте Server Explorer, щелкните правой кнопкой мыши на узле Database Diagrams базы AutoLot и выберите пункт контекстного меню Add New Diagram (Добавить новое представление). Откроется диалоговое окно, в котором можно выбирать таблицы и добавлять их в диаграмму. Выберите все таблицы из базы данных AutoLot.



 

Пожалуйста, поделитесь этим материалом в социальных сетях, если он оказался полезен!