Опубликован: 11.09.2006 | Уровень: специалист | Доступ: свободно
Лекция 4:

Работа с данными

Server Explorer

В состав Visual Studio .NET входит замечательный инструмент управления и обзора подключениями к базам данных — Server Explorer. С его помощью можно практически мгновенно создавать приложения, использующие базы данных. Создайте новый проект. Назовите его Server_Explorer. Выберите в меню View пункт Server Explorer (или воспользуйтесь сочетанием клавиш Ctrl+Alt+S). Появится окно Server Explorer. Щелкаем на Data Connections правой кнопкой мыши и выбираем пункт Add Connection (рис. 4.42).

Добавление соединения

Рис. 4.42. Добавление соединения

Появляется окно Мастера "Свойства связи с данными", с которым мы уже сталкивались (см. рис. 4.30 и рис. 4.31). Создайте самостоятельно подключение к базе данных xtreme — после того как вы это сделаете, оно появится в списке всех подключений окна Server Explorer (рис. 4.43).

В окне Server Explorer выводятся все созданные подключения к базам данных

увеличить изображение
Рис. 4.43. В окне Server Explorer выводятся все созданные подключения к базам данных

Щелкните на знак (+) около названия подключения, откройте Tables, выберите таблицу Customer и перетащите ее на форму (рис. 4.44).

Содержимое базы данных xtreme

Рис. 4.44. Содержимое базы данных xtreme

При появлении уже знакомого окна расположения пароля (см. рис. 4.27) выбираем Include Password.

На панели компонент формы появились два элемента: oleDbConnection1 и oleDbDataAdapter1. Выделяем щелчком oleDbDataAdapter1, открываем его свойства, на информационной панели нажимаем Generate DataSet. Называем объект DataSet dsCustomer и нажимаем ОК. Помещаем на форме элемент управления DataGrid, в свойствах этого элемента указываем расположение DockFill, DataSource — dsCustomer, и переходим в код формы. Добавляем уже знакомый нам код:

private void Form1_Load(object sender, System.EventArgs e)
{
  oleDbDataAdapter1.Fill(dsCustomer1);
}

Запускаем приложение. Его внешний вид ничем не отличается от приложения, рассмотренного в предыдущем примере.

Созданное подключение к базе данных xtreme теперь будет отображаться во всех последующих проектах в окне Server Explorer. Вам остается только выбирать нужную таблицу и перетаскивать ее на форму.

Вы также можете использовать окно Solution Explorer для быстрого просмотра содержимого баз данных и — если подключение было создано с правами администратора — изменять их. Откройте нужную таблицу и просто дважды щелкните на ней (рис. 4.45):

Просмотр таблицы Customers базы данных NorthwindCS

увеличить изображение
Рис. 4.45. Просмотр таблицы Customers базы данных NorthwindCS

Программирование объектов ADO.NET

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

Будет работать с теми же самыми таблицами.

Microsoft Access, база данных xtreme Таблица Customer Microsoft SQL, база данных NorthwindCS Таблица Customers

Запустите Visual Studio .NET, создайте новый проект, тип проекта — Windows Application.

Назовите его ProgrammDataMDB Назовите его ProgrammDataSQL

Размещаем на создавшейся форме элемент управления DataGrid, свойству Dock устанавливаем значение "Fill". Переходим в код формы. Подключаем соответствующие пространства имен:

using System.Data.OleDb;
using System.Data.SqlClient;

В конструкторе формы после InitializeComponent создаем объект DataAdapter:

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(CommandText, ConnectionString);
Листинг 4.1.
}  public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
SqlDataAdapter dataAdapter = new SqlDataAdapter(CommandText, ConnectionString);
}

В качестве параметров DataAdapter мы передаем CommandText и ConnectionString. Переменная типа string CommandText представляет собой обычный SQL-запрос на выборку из таблицы Customer, а переменная типа СonnectionString — это так называемая строка подключения, в которой указываются расположение базы данных, ее название, параметры авторизации и проч. Далее мы рассмотрим более подробно эти строки. Как составить эти переменные? Можно, конечно, написать вручную, но мы сейчас воспользуемся строчками, сгенерированными мастером. Откройте предыдущие проекты — VisualDataMDB и VisualDataSQL. Перейдите в код формы. Раскройте область Windows Form Designer generated code, щелкнув на знаке (+). Найдите следующие строчки:

Для CommandText:

this.oleDbSelectCommand1.CommandText = @"SELECT Address1, Address2, City, 
[Contact First Name], [Contact Last Name], [Contact Position], [Contact Title], 
Country, [Customer Credit ID], [Customer ID], 
[Customer Name], [E-mail], Fax, [Last Year's Sales], Phone, [Postal Code], Region,
 [Web Site] FROM Customer";
Листинг 4.2.
this.sqlSelectCommand1.CommandText = "SELECT CustomerID, CompanyName, ContactName, 
ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax FROM Customers";
Листинг 4.3.

Для : ConnectionString7Имя компьютера, расположение базы данных, разумеется, могут отличаться — эти значения верны только для моего компьютера.

this.oleDbConnection1.ConnectionString = @"Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Registry Path=;
Jet OLEDB:Database Locking Mode=1;Jet OLEDB:Database Password=;Data Source=""E:\Program
Files\Microsoft Visual Studio .NET 2003\Crystal Reports\Samples\Database\xtreme.mdb"";Password=;
Jet OLEDB:Engine Type=5;Jet OLEDB:Global Bulk 
Transactions=1;Provider=""Microsoft.Jet.OLEDB.4.0"";Jet OLEDB:System database=;Jet 
OLEDB:SFP=False;Extended Properties=;Mode=Share Deny None;Jet OLEDB:New Database Password=;Jet 
OLEDB:Create System Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without 
Replica Repair=False;User ID=Admin;Jet OLEDB:Encrypt Database=False";
Листинг 4.4.
this.sqlConnection1.ConnectionString = "workstation id=7EA2B2F6068D473;packet size=4096;integrated 
security=SSPI;data source=\"(local)\";persist security info=False;initial catalog=NorthwindCS";
Листинг 4.5.

Скопируйте эти строчки, начиная от названия самих переменных, затем в коде форм ProgrammDataMDB и ProgrammDataSQL в классе Form 1 объявите две переменные по две переменных типа string и вставьте скопированные значения:

string CommandText = @"SELECT Address1, Address2, City, [Contact First Name], [Contact Last Name], [Contact 
Position], [Contact Title], Country, [Customer Credit ID], [Customer ID], [Customer Name], [E-mail], Fax, [Last Year's 
Sales], Phone, [Postal Code], Region, [Web Site] FROM Customer";
string ConnectionString = @"Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Registry Path=;Jet OLEDB:Database 
Locking Mode=1;Jet OLEDB:Database Password=;Data Source=""E:\Program Files\Microsoft Visual Studio 
.NET 2003\Crystal Reports\Samples\Database\xtreme.mdb"";Password=;Jet OLEDB:Engine Type=5;Jet 
OLEDB:Global Bulk Transactions=1;Provider=""Microsoft.Jet.OLEDB.4.0"";Jet OLEDB:System 
database=;Jet OLEDB:SFP=False;Extended Properties=;Mode=Share Deny None;Jet OLEDB:New Database 
Password=;Jet OLEDB:Create System Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet 
OLEDB:Compact Without Replica Repair=False;User ID=Admin;Jet OLEDB:Encrypt Database=False";
string CommandText = "SELECT CustomerID, CompanyName, ContactName, ContactTitle, Address, City, Region, 
PostalCode, Country, Phone, Fax FROM Customers";
Листинг 4.6.
string ConnectionString = "workstation id=7EA2B2F6068D473;packet size=4096;integrated security=SSPI;data sou" +
"rce=\"(local)\";persist security info=False;initial catalog=NorthwindCS";
Листинг 4.7.

Обратите внимание на названия переменных CommandText и ConnectionString. Когда мы создаем объект DataAdapter, в качестве параметров мы можем передать названия строк, таких как cmdText и conString, или даже cmt и cns, — совершенно равноправно, не забыв, конечно же, назвать также эти переменные в классе Form1. Но сама среда VisualStudio.NET генерирует эти строки именно с такими названиями — CommandText и ConnectionString, поэтому если вы пишите их не вручную, то облегчаете работу, называя их так же, как и среда.

Возвращаемся к нашим приложениям — ProgrammDataMDB и ProgrammDataSQL. Дальнейший код будет совершенно одинаковым для обоих приложений.

Итак, создаем объект DataSet:

DataSet ds = new DataSet();

Заполняем таблицу Customer объекта ds данными из базы:

dataAdapter.Fill(ds, "Customer");

Cвязываем источник данных объекта dataGrid1 ( который мы нанесли на форму в режиме дизайна) с таблицей Customer объекта ds:

dataGrid1.DataSource = ds.Tables["Customer"].DefaultView;

Все! Запускаем оба приложения. Если вы были внимательны в самом начале, то заметили, что в базе данных xtreme таблица называется Customer, а в базе данных NorthwindCS — Customers (s на конце). Тем не менее код работает для обоих приложений. В чем же дело? Таблица, которую мы называем Customer, при вызове метода Fill объекта dataAdapter может быть названа как угодно — ее содержимое будет представлять собой извлекаемую из базы данных таблицу. При указании источника данных (DataSource) для объекта dataGrid1 мы ссылаемся именно на таблицу Customer, которая была создана при вызове метода Fill. Точнее говоря, эта таблица определена в объекте DataSet, а именно к нему мы и обращаемся для заполнения данными нашей формы в соответствии с моделью ADO.NET. Чтобы убедиться в этом, попробуйте такой код:

DataSet ds = new DataSet();
    dataAdapter.Fill(ds, "Bezimyannaya");
  dataGrid1.DataSource = ds.Tables["Bezimyannaya"].DefaultView;

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

Полный8Здесь и далее листинг указан без области Windows Form Designer generated code — когда весь пользовательский интерфейс состоит из единственного элемента DataGrid, нет особого смысла описывать его. листинг программы — подключение к базе данных xtreme:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.OleDb;

namespace ProgrammDataMDB
{
  /// <summary>
  /// Summary description for Form1.
  /// </summary>
  public class Form1 : System.Windows.Forms.Form
  {
    private System.Windows.Forms.DataGrid dataGrid1;
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.Container components = null;
    string CommandText = @"SELECT Address1, Address2, City, [Contact First Name], [Contact Last Name], [Contact Position], 
       [Contact Title], Country, [Customer Credit ID], [Customer ID], [Customer Name], [E-mail], Fax, [Last Year's Sales], 
      Phone, [Postal Code], Region, [Web Site] FROM Customer";
    string ConnectionString = @"Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Registry Path=;Jet OLEDB:Database Locking Mode=1;
      Jet OLEDB:Database Password=;Data Source="
      "E:\Program Files\Microsoft Visual Studio .NET 2003\Crystal Reports\Samples\Database\xtreme.mdb"
      ";Password=;Jet OLEDB:Engine Type=5;Jet OLEDB:Global Bulk Transactions=1;Provider=""Microsoft.Jet.OLEDB.4.0"
      ";Jet OLEDB:System database=;Jet OLEDB:SFP=False;Extended Properties=;Mode=Share Deny None;Jet OLEDB:New Database Password=;
      Jet OLEDB:Create System Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;
      User ID=Admin;Jet OLEDB:Encrypt Database=False";
      
    public Form1()
    {
      
      
      //
      // Required for Windows Form Designer support
      //
      InitializeComponent();

      OleDbDataAdapter dataAdapter = new OleDbDataAdapter(CommandText, ConnectionString);
      DataSet ds = new DataSet();
      dataAdapter.Fill(ds, "Bezimyannaya");
      dataGrid1.DataSource = ds.Tables["Bezimyannaya"].DefaultView;
      //
      // TODO: Add any constructor code after InitializeComponent call
      //
    }

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    protected override void Dispose( bool disposing )
    {
      if( disposing )
      {
        if (components != null) 
        {
          components.Dispose();
        }
      }
      base.Dispose( disposing );
    }

    Windows Form Designer generated code
    

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main() 
    {
      Application.Run(new Form1());
    }

    private void Form1_Load(object sender, System.EventArgs e)
    {
      
    }
  }
}
Листинг 4.8.

Полный листинг программы – подключение к базе данных NorthwindCS:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;

namespace ProgrammDataSQL
{
  /// <summary>
  /// Summary description for Form1.
  /// </summary>
  public class Form1 : System.Windows.Forms.Form
  {
    private System.Windows.Forms.DataGrid dataGrid1;
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.Container components = null;
    string CommandText = "SELECT CustomerID, CompanyName, ContactName, ContactTitle, Address, City, Region," +
      " PostalCode, Country, Phone, Fax FROM Customers";
    string ConnectionString = "workstation id=7EA2B2F6068D473;packet size=4096;integrated security=SSPI;data sou" +
      "rce=\"(local)\";persist security info=False;initial catalog=NorthwindCS";
      
    public Form1()
    {
      //
      // Required for Windows Form Designer support
      //
      InitializeComponent();
      SqlDataAdapter dataAdapter = new SqlDataAdapter(CommandText, ConnectionString);
      DataSet ds = new DataSet();
      dataAdapter.Fill(ds, "Customer");
      dataGrid1.DataSource = ds.Tables["Customer"].DefaultView;

      //
      // TODO: Add any constructor code after InitializeComponent call
      //
    }

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    protected override void Dispose( bool disposing )
    {
      if( disposing )
      {
        if (components != null) 
        {
          components.Dispose();
        }
      }
      base.Dispose( disposing );
    }

    Windows Form Designer generated code
    

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main() 
    {
      Application.Run(new Form1());
    }

    private void Form1_Load(object sender, System.EventArgs e)
    {
    
    }
  }
}
Листинг 4.9.
Елена Дьяконова
Елена Дьяконова

При нажатии на Сумма в примере ArbitraryMethod из Лекция 7, VS 2013 выдается ошибка: 

Необработанное исключение типа "System.InvalidOperationException" в System.Windows.Forms.dll

Дополнительные сведения: Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "lblResult" не из того потока, в котором он был создан.

Затем:

Необработанное исключение типа "System.InvalidOperationException" в mscorlib.dll

Дополнительные сведения: Для каждой асинхронной операции метод EndInvoke может вызываться только один раз.

Александр Сороколет
Александр Сороколет

Свойство WindowState формы blank Maximized. Не открывается почемуто на всё окно, а вот если последующую форму бланк открыть уже на макс открывается :-/