«Никогда не откладывайте на время выполнения то, что можно сделать во время компиляции».
Дэвид Грис, «Создание компилятора для цифровых компьютеров».
Введение
Когда мы, программисты, изучаем некоторые новые технологии, примеры иногда могут быть нашим самым большим врагом. Руководства часто разрабатываются простыми и понятными, но в то же время они могут привести к увеличению ленивого, неэффективного и даже опасного написания кода. Наиболее распространенная подобная ситуация возникает в парадигме ADO.NET. В этой статье мы рассмотрим, что значит иметь строго типизированные объекты в базе данных, что позволит вам делать это в ваших программах, несмотря на отсутствие примеров.
Более конкретно, мы увидим, как строго типизированные наборы данных создаются и используются в Visual Studio 2005. Как показано в этой статье, строго типизированные наборы данных предлагают множество преимуществ по сравнению с другим методом доступа к слабо типизированным данным. Здесь мы также увидим, что создание и использование строго типизированных наборов данных становится проще с Visual Studio 2005. Если вы хотите узнать больше, продолжайте читать.
Основы и преимущества строго типизированных объектов
Чтобы понять, что означает строгая типизация, сначала можно подумать о датировании. Если бы вы были одиноки, с каким человеком вы бы хотели встречаться? У вас могут быть конкретные критерии (например, здоровье и привлекательная внешность) или они могут быть простыми или неясными. Независимо от ваших условий, когда вы решаете, с кем проводить больше времени, вы всегда будете использовать свои собственные определенные стандарты для этих типов, которые нужно взвешивать и учитывать. Если вы умны, вы будете много думать, чтобы защитить себя от эмоциональной травмы. Вы можете обнаружить, что, например, общение с алкоголиком нестабильно, если только у них нет серьезных отношений. Однако заставить человека измениться больно и очень сложно. Поэтому ваша мудрость подскажет вам прекратить отношения еще до того, как они начнутся. Добавление пункта о запрете на употребление алкоголя в ваши критерии знакомств защитит вас от будущих душевных страданий и позволит вам сосредоточить свое время и силы на лучших кандидатах.
Вы можете быть удивлены, какое отношение эти рассуждения имеют к программированию. Не беда, пойдём со мной, милый читатель! Объекты доступа к данным ADO.NET спроектированы так, чтобы быть чрезвычайно гибкими. Когда вы читаете данные из базы данных, вы, вероятно, работаете со многими распространенными типами объектов, разрешенными обычной платформой .NET, если только у вас не возникнут особые проблемы. Применяя нашу теорию датирования, вы можете рассматривать соответствующие данные как универсальные объекты. «Пока мое свидание не доставляет особых хлопот». Не могли бы вы выразиться пояснее? Нет предела, даже если это человек или другое живое существо! Как ваш друг, я умоляю вас: «Больше стандартов! Сократите свой список!»
Точно так же, как игнорирование того, с кем вы встречаетесь, может привести к проблемам во взаимоотношениях в будущем, оставление объектов в коде без проверки также может привести к ошибкам. Кроме того, если вы позволите старым объектам перемещаться по вашей подпрограмме, вы можете не заметить, что это проблема, пока программа не заработает. Используя нашу теорию знакомств, обнаружение ошибок во время выполнения похоже на болезненный и неловкий спор вашего партнера посреди модного итальянского ресторана. Да, видите ли, если бы вы планировали заранее, на вас не смотрела бы толпа посетителей, и это не было бы смущающе. Просто применив к своему коду более строгие стандарты, вы сможете обнаружить ошибки до того, как ваша программа начнет компилироваться. Например, следующий пример кода:
string FirstName = myrow.("FirstName").ToString();
DataRow в этом примере не является типизированным, поэтому для получения нужного значения необходимо использовать имя столбца в виде строки (или вы можете выбрать использование индекса столбца в коллекции столбцов записи). К счастью, эта колонка существует. Тип данных столбца DataRow — объект. Мы предполагаем, что тип данных в столбце FirstName — строка, и мы должны явно преобразовать его в строку перед его использованием. Если имя этого столбца изменится (например, станет PersonFirstName), компилятор не сможет вас уведомить. Депрессия? Но вам не обязательно. Если ваш код будет выглядеть следующим образом, ваша жизнь станет проще, а код — надежнее.
string FirstName = PersonRow.FirstName
Во втором примере мы используем строго типизированную строку и знаем, что свойство FirstName имеет тип string; Никаких беспорядочных названий столбцов и беспорядочных преобразований типов. Компилятор уже выполнил за нас проверку типов, и мы можем спокойно выполнять остальную работу, не беспокоясь о том, правильно ли мы набрали имена столбцов.
Все остальное такое же, поэтому вы без колебаний будете использовать его вместо общего типа. Но подождите, откуда берутся строго типизированные объекты? Мне также хотелось бы сказать вам, что эти объекты создаются автоматически. Но так же, как хорошие отношения требуют времени и усилий, строго типизированные объекты требуют дополнительных усилий. Но дополнительное время, потраченное здесь, определенно того стоит, и это сэкономит в геометрической прогрессии больше времени, потраченного на «ловлю ошибок» в будущем.
Существует несколько способов добиться строгой типизации, и оставшуюся часть этой статьи мы посвятим объяснению того, как создать строго типизированный набор данных в Visual Studio 2005. Мы также сравним преимущества и недостатки этого подхода с другими подходами.
Создание строго типизированных наборов данных в Visual Studio 2005
Строго типизированные наборы данных на самом деле представляют собой просто предопределенные столбцы и таблицы обычных наборов данных, поэтому компилятор уже знает, что они содержат. Вместо свободной обертки, которая подходит вам как бейсбольная перчатка, строго типизированные наборы данных подходят как перчатка. Каждая последующая версия Visual Studio упрощает обработку строго типизированных наборов данных. В следующем примере мы будем использовать базу данных AdventureWorks SQL Server 2005. Просто выполните следующие действия:
1. Откройте Visual Studio и создайте новый веб-сайт ASP.NET.
2. В окне обозревателя решений щелкните правой кнопкой мыши, чтобы добавить новый элемент, и выберите DataSet. Назовите его AdventureWorks.xsd (см. скриншот). Visual Studio порекомендует вам поместить файл DataSet в файл App_Code, и вам просто нужно нажать «Согласен».
3. После открытия AdventureWorks.xsd в режиме разработки запустится мастер настройки TableAdapter. На этом этапе нажмите «Отмена», и мы перетащим нужную таблицу из обозревателя серверов.
4. Найдите базу данных AdventureWorks на панели инструментов обозревателя серверов. (Если вы не установили базу данных AdventureWorks, вы можете перейти на страницу загрузки Microsoft «Образцы SQL Server 2005 и образцы баз данных», чтобы загрузить ее и некоторые другие образцы SQL Server 2005.)
5. Перетащите таблицу SalesOrderHeader и таблицу SalesOrderDetail в окно конструктора DataSet. Окно должно выглядеть как на скриншоте. Что мы видим? Всякий раз, когда мы добавляем таблицу, Visual Studio создает строго типизированную таблицу DataTable (с тем же именем, что и исходная таблица) и TableAdapter. Этот DataTable определил для нас каждый столбец. TableAdapter — это то, что мы используем для заполнения таблицы. По умолчанию существует метод Fill() для получения каждой строки данных из исходной таблицы.
В действительности этот строго типизированный набор данных вернет все записи из обеих таблиц. Но база данных AdventureWorks содержит много информации о заказах, так почему бы не создать более явный запрос? Мы можем добавить методы к объекту TableAdapter для получения определенного набора подзаписей. Щелкните правой кнопкой мыши SalesORderHeaderTableAdapter и выберите Добавить | Запрос. Выберите «Использовать операторы SQL» и нажмите «Далее», затем выберите «ВЫБРАТЬ, который возвращает строки» и нажмите «Далее». Недавно введите в окно следующий запрос (или вы можете использовать Query Builder для выполнения этой работы):
ВЫБИРАТЬ
SalesOrderID, RevisionNumber, OrderDate, DueDate, ShipDate,
Статус, OnlineOrderFlag, SalesOrderNumber, PurchaseOrderNumber,
Номер счета, идентификатор клиента, идентификатор контакта, идентификатор продавца, идентификатор территории,
BillToAddressID, ShipToAddressID, ShipMethodID, CreditCardID,
CreditCardApprovalCode, CurrencyRateID, SubTotal, TaxAmt, Freight,
TotalDue, Комментарий, rowguid, ModifiedDate
FROM Sales.SalesOrderHeader
ГДЕ (ДатаЗаказа > @ДатаЗаказа)
Этот SQL-запрос представляет собой простой запрос SELECT, в котором для фильтрации результатов используется параметр @OrderDate. Это избавит нас от возврата всех записей в базе данных. Оставьте флажки «Заполнить DataTable» и «Вернуть DataTable» и нажмите «Готово». После добавления этого оператора SELECT ваш конструктор должен выглядеть так, как показано на снимке экрана, с дополнительным запросом в разделе SalesOrderHeaderTableAdapter.
После того, как строго типизированный набор данных создан, мы можем легко отобразить данные на странице ASP.NET с помощью нескольких строк кода. Создайте новую страницу ASP.NET на веб-сайте и переключитесь в режим разработки. Перетащите на него элемент управления GridView и оставьте его идентификатор GirdView1. Затем перейдите на страницу исходного кода и введите пространство имен AdventureWorksTableAdapters над файлом (синтаксис в C# использует AdventureWorksTableAdapters;). Наконец, добавьте следующий код к событию Page_Load:
// Создаем адаптер SalesOrderHeaderTableAdapter
SalesOrderHeaderTableAdapter salesAdapter =
new SalesOrderHeaderTableAdapter()
// Получение заказов, произошедших после 1 июля 2004 г.
AdventureWorks.SalesOrderHeaderDataTable Заказы =
salesAdapter.GetDataBy(new DateTime(2004, 7, 1));
// Привязываем результаты заказа к GridView.
this.GridView1.DataSource = Заказы;
это.GridView1.DataBind();
Код очень прост. Мы создаем экземпляр SalesORderHeaderTableAdapter для заполнения таблицы данных. Здесь следует отметить, что в отличие от обычного DataTable мы объявляем объект типа SalesORderHeaderDataTable. Мы вызываем метод GetDateBy() и передаем объект DateTime для заполнения данных. Также обратите внимание, что полученная команда также строго типизирована, поэтому мы должны передать объект DateTime вместо обычного объекта. Скриншот ниже — результат приведенного выше примера кода.
Помимо использования кода для привязки набора результатов к GridView, вы также можете использовать ObjectDataSource, установить для его свойства TypeName значение AdventureWorksTableAdapters.SalesOrderHeaderTableAdapter и установить для его SelectMethod значение GetData или GetDataBy.
Помимо отсутствия необходимости писать код для подключения к базе данных, еще одним большим преимуществом использования строго типизированного набора данных является отсутствие в нашем коде строк с именами столбцов, которые компилятор не может проверить. Нам также не нужно выполнять какое-либо преобразование типов. Если схема базы данных изменится, просто обновите файл AdventureWorks.xsd, и мы обнаружим, что все связанные изменения автоматически вносятся во время компиляции.
Другие методы создания строго типизированных приложений доступа к данным
Помимо использования строго типизированных наборов данных существуют и другие способы реализации строгой типизации в ваших программах. Вы можете создавать собственные классы, более легкие, чем DataSets, и более совместимые с вашей базой данных. Есть также сторонние разработчики программного обеспечения, которые разработали инструменты для автоматизации этого процесса. Один из наиболее особенных и мой любимый — LLBLGen Pro. Однажды я написал о нем книгу: Rapid C# Windows Development: Visual Studio 2005, SQL Server 2005 и LLBLGen Pro. (Вы можете бесплатно прочитать 1/3 книги на моем веб-сайте.) Еще один популярный инструмент — CodeSmith. Даже Microsoft разрабатывает небольшой инструмент под названием DLINQ, но он все еще тестируется и, по оценкам, будет запущен как минимум до следующего года.
Если вы используете сильный подход Visual Studio к наборам данных, одним из неоспоримых преимуществ является то, что вам не нужно приобретать дополнительное программное обеспечение. Все эти решения имеют разные функции и преимущества, но основными преимуществами являются надежность, меньшее количество ошибок и меньше времени, затрачиваемого на отладку. Также легче проверить влияние изменений схемы базы данных и выполнить обслуживание. Надеюсь, вы осознали преимущества строгой типизации. Удачи в развитии (и знакомствах тоже)!
Джозеф Канцлер
Вложения
Загрузите код, рассмотренный в этой статье.
Об авторе
Джозеф Ченселлор — разработчик C# из Южной Калифорнии, который получил немало реляционных травм. Он ценит любые отзывы и предложения. Посетите его блог или прочитайте первые пять глав его книги о Visual Studio 2005, SQL Server 2005 и. LLBLGen Pro
Исходный адрес: http://aspnet.4guysfromrolla.com/articles/020806-1.aspx.