Въведение
в…
Microsoft
.NET
Съдържание
За какво служи .NET?
Според сайта на Microsoft, .NET е софтуер,
който свързва информация, хора, системи и устройства; обхваща клиенти, сървъри
и инструменти за разработка. Състои се от:
С думите “всякакъв софтуер” Microsoft може би
малко преувеличават. И все пак с .NET се създават както Web услуги и
приложения, така и Windows софтуер. Хубавото е,
че всичко е възможно най-уеднаквено и с почти едни и същи познания можете да
създавате както софтуер за Web, така и за Windows. Друго голямо предимство е,
че едно и също .NET приложение може да работи на всякакви устройства – от PC до
smart phone – при условие, че на устройството може да се инсталира .NET Framework. Резюме
В тази статия ще ви запознаем с основните концепции, които
стоят зад създаването на .NET
приложения. Ще разгледаме накратко средата за разработка Microsoft
Visual Studio 2005 и езика C# като
средства, с които се създава софтуер. След това по-подробно ще
разгледаме как в .NET
се осъществява работата с бази от данни и как се създава потребителски
интерфейс за Windows и Web. Накрая, в синтезиран
вариант ще разгледаме перспективите пред тази технология. История
Някои от технологиите в .NET първоначално са разработени от
Microsoft като тяхна версия на Java. През 1998г. Microsoft решават повече да не
използват Java технологиите на SUN и да създадат свой аналог. Съществуващият тогава
продукт Microsoft J++ за създаване на Java приложения става основа за
създаването на .NET, а Java виртуалната машина OmniVM е отправна точка при
разработката на .NET аналога си CLR. През 2002г. .NET Framework 1.0 се появява
на бял свят заедно със средата за разработка на приложения Microsoft Visual
Studio .NET. След това последователно излизат .NET Framework 1.1 интегриран с
Microsoft Visual Studio .NET 2003 и .NET Framework 2.0 заедно с Microsoft
Visual Studio 2005. Windows Server 2003 е първата операционна система с вграден
в нея .NET Framework. Основата на .NET
Визията на
Microsoft за .NET е да създадат платформа, която да може да обединява разнородни сървъри, да интегрира бизнес процесите на различни компании по стандартен начин, и да предоставя на потребителите достъп до информацията, която им е нужна, по всяко време, от всяко място и от всяко устройство. Microsoft са направили
голяма крачка напред към реализирането на тази визия, като са
поставили една стабилна технологична основа за разработка и изпълнение на
приложения – Microsoft .NET Framework. .NET Framework e
среда за разработка и изпълнение на приложения. Тя предоставя програмен модел,
библиотеки от типове и единна инфраструктура за разработка на
приложения и поддържа различни езици за програмиране. Приложенията,
базирани на .NET Framework, се компилират до междинен код (на езика IL) и се изпълняват от средата за изпълнение на .NET
Framework – CLR. Компилираният .NET код може да работи
без да се прекомпилира върху различни платформи, за които има
имплементация за .NET Framework (Windows, Linux, FreeBSD). Можем да
разделим .NET Framework на два основни компонента: 1) Common Language Runtime (CLR) – представлява
виртуална машина, която изпълнява .NET кода и осигурява
различни услуги, като управление на паметта и ресурсите, управление на
сигурността, на изключенията, осигуряване на безопасността на типовете и др. Компилираният код се нарича още управляван код (managed code), защото е
съвместим с тези услуги. 2) Framework Class Library (FCL) –
представлява основната библиотека от типове, които се използват при
изграждането на .NET приложения.
Съдържа основната функционалност за разработка,
необходима за повечето приложения, като вход/изход, връзка с бази данни, работа
с XML, изграждане на Web
приложения, използване на Web
услуги, изграждане на графичен потребителски интерфейс и др. Стандартните
класове и типове от FCL можем да използваме навсякъде, където има инсталиран
.NET Framework. .NET Framework позволява на разработчика да използва различни езици за
програмиране, както и да интегрира в едно приложение компоненти, разработвани
на различни езици. Възможно е дори клас, написан на един език, да бъде наследен
и разширен от клас, написан на друг език. Microsoft .NET Framework поддържа
стандартно езиците C#, VB.NET, Managed C++ и J#, но трети доставчици предлагат
допълнително .NET версия на още много други езици, като Pascal, Perl, Python,
Fortran, Cobol и други. Това
езиково разнообразие е възможно, благодарение на дефинираната в стандартите ECMA-335 и ISO 23271:2003 Common Language
Infrastructure (CLI). Всички .NET езици поддържат
общата езикова спецификация – Common Language
Specification (CLS), която е част от тези
стандарти. CLS дефинира общите и задължителни характеристики, които един
програмен език трябва да притежава, за да бъде съвместим с останалите .NET
езици. Тази спецификация има за цел да минимизира разликите между .NET езиците.
CLS, например, налага ограничението да се прави разлика между малки и главни
букви в имената на типовете. Ако нарушим това
правило, нашият код ще се компилира, но ще загуби съвместимостта си с CLS и другите .NET езици. Друго
ограничение, което CLS налага, e езиците да бъдат обектно-ориентирани.
Това означава, че за да бъде направен даден език съвместим с CLS и .NET Framework, той трябва да
бъде разширен да поддържа класове, интерфейси,
свойства, изключения и всички останали елементи на
обектно-ориентираното програмиране с .NET. CLI дефинира също и Common
Type System (CTS), в която се описват съдържанието и начина на дефиниране
на типовете, модификаторите за достъп, начините за наследяване, времето на
живот на обектите и много други технически характеристики. CTS гарантира, например, че типът String в C# ще е същият като String във Visual Basic.NET, също така налага
задължението всички типове да наследяват системния тип System.Object,
дори и примитивните, благодарение на което извикването “5.ToString()” е напълно валидно. Тези
изисквания се налагат, защото кодът на всеки един от .NET езиците трябва да се компилира
(преобразува) до код на езика Intermediate
Language (IL). По
този начин, дори да имате класове, писани на 20 различни езика, след компилация
до IL, полученият код е подходящ за
изпълнение от виртуалната машина. Междинният език
IL, е език за програмиране от ниско ниво, подобен на асемблерните езици. За
разлика от тях, обаче, IL е от много по-високо ниво, отколкото асемблерите за
съвременните микропроцесори. IL е обектно-ориентиран език. Той разполага с
инструкции за заделяне на памет, за създаване на обект, за предизвикване и
обработка на изключения, за извикване на виртуални методи и други инструкции,
свързани с обектно-ориентираното програмиране. Тъй като не е
процесорно-специфичен, IL предоставя голяма гъвкавост и възможност за
изпълнение на кода върху различни платформи чрез компилиране до съответния за
платформата машинен език. Имплементацията на IL в .NET Framework се нарича Microsoft Intermediate Language (MSIL). IL може да има и други имплементации в
други платформи и среди за изпълнение на .NET код. При
компилацията на вашия код до IL код
се създават и т. нар. метаданни. Те съдържат
описание на типове данни, класове, интерфейси, свойства, полета, методи,
параметри на методите и други, както и описание на библиотеки с типове,
описание на изисквания към сигурността при изпълнение и т. н. Кодът, заедно с
метаданните си, образува най-малката самостоятелна градивна единица в .NET Framework – асемблито. Асемблитата се съдържат в .EXE или .DLL файлове и
съдържат цялата необходима информация (в метаданните), за да бъдат изпълнени от
виртуалната машина. Изпълнението на дадена програма накратко протича така:
Всички нужни за работата класове и типове се зареждат и се извършва процес,
известен като верификация. Той проверява дали IL кодът е безопасен – дали не се
опитва да осъществява директен достъп до паметта, дали не се опитва да
заобикаля механизмите за сигурност и т. н. Ако системният администратор е
определил кода за сигурен (trusted) неговото верифициране може да бъде
прескочено. Следва JIT (Just In Time) компилацията –
до машинен (native) код се
компилира само този IL код, който в
дадения момент трябва да бъде изпълнен. За разлика от виртуалната машина на Java, CLR не интерпретира
междинния език, а го компилира при нужда и ако дадено парче код трябва да се
изпълни пак, изпълнява вече използваният машинен код. По този начин бавното
интерпретиране се избягва и бързодействието на .NET програмите е почти същото като и на досегашните Win32 приложения.
Какви знания ми трябват?
За да разберете напълно тази статия, ще ви е от полза да
имате основни познания по програмиране и обектно-ориентирано програмиране. Също
така при разглеждането на работата с данни, ще са ви необходими знания,
свързани с базите данни и езика SQL. Инсталиране
За да създавате приложения за .NET Framework, имате нужда както от него, така и от Visual Studio. Безплатни trial дистрибуции на Visual Studio 2005, които включват и .NET Framework, можете да намерите на microsoft.com http://msdn.microsoft.com/vstudio/products/trial/ От този сайт бързо и лесно можете да изтеглите например някоя
от Visual Studio 2005 Express Editions,
които ще бъдат безплатни в продължение на една година. За примерите от
тази статия ще ви бъдат полезни Visual C# 2005 Express Edition, Visual
Web Developer 2005 Express Edition и SQL Server 2005 Express Edition. Visual Studio 2005
Увод
До момента се запознахме с .NET Framework, с неговата архитектура. Време е да разгледаме и средата за разработка на .NET приложения, която Microsoft предоставят на разработчиците. Това е продуктът Microsoft Visual Studio 2005 (VS2005). С негова помощ можем да извършваме всяка една от типичните задачи, свързани с изграждането на едно приложение – писане на код, създаване на потребителски интерфейс, компилиране, изпълняване и тестване, дебъгване, проследяване на грешките, създаване на инсталационни пакети, разглеждане на документацията и други. Настройки
При първоначалното си стартиране VS2005 ви пита каква е основната дейност, която ще вършите. В зависимост от главните цели на разработчика, някои функционалности на средата са по-важни от други и Visual Studio се настройва така, че това, което ви е най-нужно, да бъде най-лесно достъпно и най-удобно. Все пак, можете да направите VS2005 да изглежда по различен начин, който най-много ви допада – можете да добавяте или махате ленти с бутони, както и самите бутони върху тях, същото важи и за различните прозорци с информация, инструменти, визуализации и т.н., които се избират от менюто View. Всеки обект от работното поле може да се слага в различните краища на екрана или да “виси” някъде по средата, различните прозорци могат да се подреждат заедно по всякакъв начин или да се слагат един върху друг. Всички тези операции стават бързо и лесно, само с използване на мишката. ● Когато посочите някой от тях, ще видите мястото, където ще
сложите вашия прозорец ако, отпуснете бутона на мишката в този момент: външните
четири символа обозначават позиции по съответните краища на работната площ,
вътрешните – по краищата на прозореца, а символът по средата означава, че ще
поставите вашия прозорец точно върху долния и двата ще се припокриват. ● Освен да местите обектите по работното поле,
можете да променяте и много други настройки, свързани с цветовете в редактора,
със стойности по подразбиране (например пътища до файлове) или с други,
по-специфични неща. Това можете да направите като изберете Options… от менюто Tools. ● Във VS2005 съществува възможност за импорт/експорт на настройки. Когато направите своите настройки за това как да изглежда средата ви, изберете Import and Export Settings… от менюто Tools. Избирате Export selected environment settings, коя част от настройките си да запазите и в кой файл. Вече в този (.vssettings) файл са вашите лични настройки. Ако отидете например на друг компютър, е достатъчно да запишете този файл, да изберете Import selected environment settings, да укажете къде се намира той и отново ще имате среда, пригодена точно за вас. Ако пък вашите настройки ви омръзнат или не ви хареса как сте разбъркали всичко, избирате Reset all settings и всичко е като отначало. Писане на кодВсе пак VS2005
е за писане на код, така че да обърнем внимание на това. Пакетът Visual
Studio 2005 поддържа стандартно езиците за програмиране Microsoft C# .NET,
Microsoft Visual Basic .NET, Microsoft C++ .NET (managed/unmanaged) и Microsoft Visual J#. За да използвате
език, различен от тези, които
Microsoft предлага стандартно, трябва да инсталирате нужните добавки към VS2005. Текстовият редактор за код на VS2005
поддържа всички утвърдени съвременни функции на редакторите за сорс код –
синтактично оцветяване за по-лесно визуално възприемане
на кода и намаляване на грешките, автоматично довършване на започнат израз,
автоматично извеждане на помощна
информация по време на писане, средства за навигация по кода и много други. ● VS2005 поддържа IntelliSense функционалност за подсказване на имена на класове, методи и променливи. Тя предоставя огромно улеснение за начинаещите .NET програмисти, тъй като позволява те да разгледат на място възможностите и да изберат от списък тази, която ги интересува. Така се спестяват усилия, време за изписване на името и се намалява значително вероятността за досадни "правописни" грешки. Пример: Отворете File/New/Project…, изберете в ляво типът да е Visual C#, Windows, а в дясно изберете
Console Application. Получава се сорс на програма, която не прави нищо. Ако напишем в
метода Main() командата Console.Write("Hi"); ще се изпише Hi на екрана. Когато
започнете да пишете Console, се появява падащо меню, в
което са всички възможни смислени (от гледна точка на езика C#) думи, които бихте могли да
използвате. При маркиране на някоя от думите в менюто, отстрани се появява
обяснение за нейния смисъл:
● Друго улеснение са т. нар. снипети. Те представляват кратък запис на нещо
по-дълго. Някъде в сорса си кликнете с десния бутон на мишката и от
менюто изберете Insert Snippet... Показва се списък
с имената на всички дефинирани снипети. Двойно кликване с мишката върху името
на снипета ще доведе до появяването на кода, на който то съответства, там, където
сте кликнали. Ако пък знаете името на снипета, който ви трябва, можете да го
напишете и с натискане на Tab съответният код ще се
появи. Пример: Напишете for и натиснете два пъти Tab. Получавате следното:
● VS2005
поддържа преработка (Refactoring)
на кода. С него лесно можете да обособите даден фрагмент от програмата в
отделен метод или клас; да преименувате дадена променлива или клас така, че да
сте сигурни, че това ще се случи навсякъде в сорса ви, но само където има
нужда; да размените местата на аргументите на метод и да знаете, че това се е
случило навсякъде в програмата ви. Пример: Имате цикъл for с управляваща променлива i. В даден момент може да
решите, че това име не е подходящо, и да го замените с count например. Ако използвате Find/Replace можете да
направите промяната, но ще постигнете и нежелани промени – например if ще се превърне в countf, Main в Macountn и т.н. За да не се
случва това, маркирайте името на променливата, натиснете десния бутон на
мишката и от контекстното меню изберете Refactor/Rename… Изберете
подходящото ново име и след натискане на OK получавате искания резултат. ●
Във VS2005 можете
да правите тестов проект, който няма да ви трябва, без да се налага да
създавате директории за него – просто след края на работата си не го запазвате.
Ако пък решение (Solution)
съдържа само един проект, няма да виждате нещата, свързани с решението, защото
те не са нужни. По този начин VS2005 ви
помага да се концентрирате над конкретната си дейност. Затова, например, е въведено и улеснение в
следенето на това, коя част от кода сте променяли. В левия край на реда, на който
има промяна, или на реда, на който сте изтрили ред, стои жълта линия. Ако
запазите промените във файла, тази линия се оцветява в зелено. Друго, за което
се грижи Visual Studio е
да не губите написания код ако сте забравили да го запазите и нещо се случи
(например токът спре). Това става, като на всеки пет минути сорсът се запазва,
за да може след евентуален проблем да се възстанови. ●
При търсенето на грешки също можете да се съсредоточите върху своята работа,
защото дебъгерът пропуска системните методи и визуализира само писаните от вас.
Улеснение е, че можете да променяте кода си без да прекъсвате изпълнението на
програмата, което спестява много време. Използването на breakpoint-и дава по-широки възможности,
като например броене на преминаванията през даден ред, изписване на нещо или
изпълнение на макрос, дори и възможността изпълнението да не прекъсне при
срещането на съответния breakpoint. Създаване на инсталационен
пакет
Освен стандартните шаблони за всеки език за програмиране,
Visual Studio 2005 ви предлага и шаблони за инсталационни пакети. Така се
затваря цикълът на разработка на приложения. Можете да използвате готовите
стандартни форми и технологии за инсталация и/или да добавите свои собствени
към инсталационния пакет. След като тази стъпка е завършена, можете да
разпространявате своето приложение до крайните потребители. Технологиите на
инсталиране, които ни предлага Visual Studio 2005, са приложими за почти
всякакви приложения, независимо от това дали са конзолни, Windows Forms, Web приложения или библиотеки
с типове. За да създадете инсталационен пакет, изберете File/New/Project… (или добавете проект към
някой Solution) и в
ляво изберете Other Project Types/Setup and Deployment. В дясно изберете Setup Wizard и следвайте
инструкциите. Получаване на помощ
При инсталиране на Visual Studio 2005 с него се инсталира
неговата документация и по желание документацията на Microsoft .NET Framework
(т.нар. MSDN Library). Те автоматично се интегрират в средата за разработка и
позволяват да получим т. нар. контекстно-ориентирана помощ. Например, докато
използваме даден клас от .NET Framework, VS2005 ни показва неговата
документация в прозореца Dynamic Help.
Интегрираната помощна система във VS2005 позволява при натискане на клавиша [F1] да
получим информация за текущия клас, свойство или компонент, който е на фокус.
Това значително улеснява разработчика. Разширяване
Интегрираната среда за разработка Microsoft Visual Studio
.NET е така проектирана, че лесно да може да се разширява с допълнителни модули
и нови възможности. Съществуват стотици добавки (plug-ins) за VS2005, които
добавят поддръжка на нови езици и нови технологии, подпомагат процеса на
разработка по различни начини, добавят интеграция с други продукти и т. н.
Някои от тях са свободни, докато други са комерсиални продукти. Благодарение на
добре документираните програмни интерфейси за интеграция с VS2005 програмистите
могат да добавят и собствени добавки за средата. Visual C#Кратко описание на езика
C# е обектно ориентиран и типово безопасен (type-safe) език за програмиране. Той е наследник на C и C++. Заедно с това притежава лекотата при използване, характерна за Java и притежава по-малко от 90 ключови думи. Езикът е специално проектиран за .NET Framework и е съобразен с неговите особености. Може да се използва за създаване на традиционни Windows приложения, клиент-сървър приложения, XML Web услуги, приложения работещи с бази данни, приложения за мобилни устройства и други. С# е обектно-ориентиран език за програмиране. В него залягат основните принципи на обектно-ориентираното програмиране, като енкапсулация на данните, наследяване и полиморфизъм. В .NET Framework всички типове данни наследяват системния тип System.Object и придобиват от него някои общи методи, свойства и други характеристики. Вследствие на това в C# всички данни се третират като обекти. Дори примитивните типове, чрез въвеждането на автоматичното им опаковане (boxing) и разопаковане (unboxing) се превръщат в обекти. Езикът C# е насочен към компонентно-ориентираното
програмиране, при което софтуерът се изгражда чрез съединяване на различни
готови компоненти и описание на логиката на взаимодействие между тях. При
проектирането на .NET Framework и езика C# компонентният подход е залегнал на
най-дълбоко архитектурно ниво. .NET Framework дефинира общ компонентен модел,
който установява правилата за изграждане и използване на компоненти за всички
.NET приложения. С# е силно типизиран (strongly-typed) и типово безопасен. В него не се използват указатели към паметта, които създават много проблеми в по-старите езици за програмиране. Вместо тях се използват специални силно типизирани указатели, които се наричат референции (references). Използването на референции вместо указатели решава проблемите, които възникват от неправилната работа с указатели и директния достъп до паметта. В .NET Framework управлението на паметта се извършва почти изцяло от CLR. Всъщност в C# може да се използват указатели (като тези в C и C++) чрез запазената дума unsafe, но това обикновено не се препоръчва, защото лишава програмата от типова безопасност и позволява неправилна работа с паметта. В С# не може да се излезе от границите на масив или символен низ. При опит да бъде направено това, се получава изключение, което може да бъде прихванато и обработено. В езици като C, C++ и Pascal излизането от границите на масив води до достъп до памет, използвана от други данни и най-често предизвиква сривове или неочаквано поведение на програмата. Приложенията, реализирани с езика C#, могат да взаимодействат с друг Windows софтуер, като например COM обекти или Win32 DLL файлове. Така се разширяват възможностите на езика. В С# няма разделяне на хедър файлове и файлове с имплементация, както в C и C++. Това спестява много проблеми и улеснява поддръжката на сорс кода. В C# всичкият програмен код на даден клас е в един файл. Взаимодействие с .NET Framework
C# се поддържа от .NET Framework. Сорс кодът, написан на C#, се компилира до междинен език (IL), който се съобразява с общата езикова спецификация (CLI). Полученият междинен код, заедно с ресурси като битмапове и низове, се запазва като асембли с разширение .EXE или .DLL. В асемблито се съдържа информация относно неговата структура. Когато една C# програма се изпълнява, асемблито се зарежда в CLR. CLR може да изпълни някакви действия в зависимост от информацията, съдържаща се в описанието на асемблито. След това, ако изискванията за сигурност са спазени, CLR извършва JIT компилация, за да превърне IL кода в машинен код. CLR предоставя и други услуги, свързани с автоматично събиране на боклука (garbage collection), управление на изключения (exception handling) и управление на ресурсите. Кодът, който се изпълнява от CLR се нарича “управляван код” (managed code). Тази диаграма показва взаимодействието между сорс кода на C#, основната библиотека от класове (Base Class Library), асемблитата и CLR.
.NET
Framework включва обширна библиотека с повече от 4000 класа,
организирани в пространства от имена (namespaces), които предлагат полезна функционалност за неща като
вход/изход, манипулация на низове, XML parse-ване и контроли за Windows Forms. Типичните C# приложения използват библиотеката с класове на .NET Framework, за да се
справят с всекидневната занаятчийска работа. Какво включва една C# програма?
Тази точка накратко предава знанията, които са нужни при писане на една програма на езика C#. Ще започнем с една проста Hello world програма. Един примерен код на програма, която
извежда на екрана символния низ “Hello world” би изглеждала така: using System; // A "Hello
World!" program in C# namespace HelloWorld { class Hello { static void Main() { System.Console.WriteLine("Hello World!"); } } } Нека разгледаме отделните части на тази програма: Последователността от символи // превръща символите от реда след нея в коментар. За създаване на коментари от по няколко реда, текстът може да се постави между символите /* и */. Всичко между тях се счита за коментар. Всяка C# програма
съдържа Main() метод, където започва и завършва работата на дадената програма. Main() методът
е статичен метод, който се намира в клас или структура. В тази Hello World програма той се
намира в клас наречен Hello. Main() методът може да връща void или int. Той може да приема и аргументи. Параметърът на Main() методът е масив от тип string. Той съдържа подадените от командния ред параметри към програмата. За разлика от C++ този масив не съдържа името на изпълнимия (EXE) файл. Пространства от имена (namespaces) Пространствата от имена са средство за организиране на кода в софтуерните проекти. Те съдържат дефиниции на класове, структури, изброени типове и други пространства от имена, като по този начин осигуряват логическо групиране на множества от типове. Пространствата от имена не могат да съдържат дефиниции на функции и данни, тъй като езиците от .NET Framework са строго обектно-ориентирани и такива дефиниции се допускат само в тялото на типовете. В тази програма е дефинирано едно именувано пространство HelloWorld. Обикновено C#
програмите използват възможностите за вход и изход, предоставени от
библиотеката на .NET
Framework. Следният израз: System.Console.WriteLine("Hello
World!"); използва метода WriteLine() на класа Console,
за да извежда низ на екрана, последван от нов ред. По-нататък са описани някои
от входно-изходните възможности на езика. Ако се използва директивата using System; класовете
и методите в System могат да се използват без да се указва
пълното им име. Например, може да се използва Console.WriteLine() вместо System.Console.WriteLine(). Можете да компилирате програмата си като създадете проект
във Visual Studio 2005.
Също така, можете да използвате команден ред. Използвайте Visual Studio Command Prompt, за да
компилирате своите програми. Освен това, може да се използва Command Prompt на Windows, но първо, когато той се отвори, трябва да се стартира vsvars32.bat, който се намира
в директорията Common7\Tools в
директорията, където е инсталирано вашето Visual Studio. Сега,
ако сте създали някакъв C# сорс
код, можете да използвате инструмента csc, за да го компилирате.
Сорс файла трябва да има разширение .cs. C# сорс файловете имат такова разширение. Ето как може да се
компилира един файл – в конзолата
напишете: csc
Hello.cs Получава се изпълним файл Hello.exe. Структурата на една C# програмаC# програмите могат да се състоят от един или повече файлове. Всеки файл може да съдържа нула или повече именувани пространства. Едно именувано пространство може да съдържа класове, структури, интерфейси, енумератори и делегати в добавка към други именувани пространства. Типове данниC# е
силно типизиран език. Ето защо всеки обект и променлива трябва да имат
деклариран тип. Типовете данни могат да се разделят на вградени (такива като int или
char) или
дефинирани от потребителя (като класове или интерфейси). Типовете данни също
могат да се разделят на типове по стойност (value types) и типове по референция (reference types). Типовете по стойност (стойностни типове) директно съдържат своята
стойност и се съхраняват в стека.
Те се предават по стойност.
Типовете по референция (референтни
типове) представляват силно
типизирани указатели към стойност в динамичната памет. Те се предават по референция (адрес) и се унищожават от garbage collector, когато не се използват повече от програмата. ● Типовете по стойност (стойностни типове) са
примитивните типове, изброените типове и структурите. ● Типовете по референция (референтни типове)
са класовете, интерфейсите, масивите и делегатите. На всички типове в C# съответстват типове от общата система
от типове (Common Type System –
CTS) на .NET Framework. Например, на примитивния C# тип int съответства типа System.Int32
от CTS. Преобразуване на типовеИма два типа преобразувания на примитивните типове –
преобразуване по подразбиране (implicit conversion) и изрично преобразуване
(explicit conversion). В C# преобразуването по подразбиране е позволено, когато
е безопасно. Например от int към long, от float към double, от byte към short: short a = 10; int b = a; Изричното преобразуване се използва, когато преобразуваме към по-малък тип или типовете не са директно съвместими. Например, от long към int, от double към float: int a = 10; short b = (short)
a; ИдентификаториИдентификаторите в С# се състоят от последователности от букви, цифри и знак за подчертаване, като винаги започват с буква или знак за подчертаване. В тях малките и главните букви се различават. Идентификаторите могат да съдържат Unicode символи. Например: int ала_бала = 14; char _aAa = ‘v’; Оператори
Операторите в С# са много близки до операторите в C++ и Java
и имат същото действие и приоритет. В C#, както и в C++, операторите могат да се предефинират. Програмни конструкцииПрограмните конструкции в C# са много близки до тези в C/C++ и Java. Има някои специални конструкции. Те са lock – за синхронизирано изпълнение, checked, unchecked – за контрол на аритметичните препълвания, unsafe – за директен достъп до паметта чрез указатели, fixed – за фиксиране на местоположението в паметта при работа с неуправляван код. Следват някои конструкции, които не се използват в C/C++ и Java: Свойства
(Properties) Свойствата са членове, които предлагат гъвкав механизъм за
четене, записване или пресмятане на стойности от private полетата. Свойствата могат
да бъдат използвани като public членове, но всъщност те са специални
методи. Те предоставят лесен достъп до данните като заедно с това осигуряват
сигурността и гъвкавостта на методите. Свойствата могат да имат два компонента (accessors): код за прочитане на стойността (get accessor) и код за присвояване на стойността (set accessor). Когато създаваме свойства можем да предоставим дефиниции на двата компонента, както и само на един от тях, но задължително трябва да е дефиниран поне единият. Пример: Класът TimePeriod пази период от време.
Вътрешно класът пази времето в секунди, но има свойство Hours, което позволява на клиента да укаже периода от време в
часове. class TimePeriod { private double seconds; public double Hours { get { return seconds / 3600; } set {
seconds = value * 3600; } } } … TimePeriod time = new TimePeriod(); time.Hours = 5; Индексатори
(Indexers) Индексаторите позволяват инстанции на класове или структури
да бъдат индексирани по същия начин, както масивите. Индексаторите много
приличат на свойствата. Разликата е, че техните accessor методи приемат параметри. Пример: Класът Sample има един индексатор, който
позволява да се достъпват отделните елементи на масива arr, който
е private член
на класа. class Sample { private string[] arr
= new string[100]; public string this[int i] { get { return arr[i]; } set { arr[i]
= value; } } } class Program { static void Main(string[] args) { Sample stringCollection = new
Sample(); stringCollection[0]
= "Hello, World"; System.Console.WriteLine(stringCollection[0]); } } Делегати
(Delegates) Делегатите са типове, които пазят референция към метод. Когато един делегат се асоциира с метод той се държи точно като него. Делегата може да се използва като всеки друг метод с параметри и връщана стойност. Пример: public delegate
int PerformCalculation(int x, int y); Всеки метод, който има същата сигнатура може да се присвои на делегата. Така могат да се променят програмно извиквания към функции и да се добавя код към съществуващи класове. Използвайки класове методите могат да се предават като параметри. Например един алгоритъм за сортиране може да получава като параметър метод, който сравнява два елемента. Така алгоритъма може да се реализира по-общо. Атрибути
(Attributes) Атрибутите предоставят мощен метод за асоцииране на декларативна информация със C# код (типове, методи, свойства и т.н.). Има два вида атрибути: атрибути, които са дефинирани в библиотеката с класове на CLR и такива, които програмистът може да създава. Атрибутите се използват вътрешно от .NET Framework за различни цели – при сериализация на данни, за описание на различни характеристики, свързани със сигурността на кода, за задаване на ограничения за оптимизациите от JIT компилатора, така че кодът да може да се дебъгва, за взаимодействие с дизайнера на средата за разработка при създаване на .NET компоненти, при взаимодействие с неуправляван код, при работа с Web услуги, в ASP.NET потребителски контроли и на много други места. Пример: Ето така могат да се приложат два атрибута към даден метод [MyFirstAttribute, MySecondAttribute] public void SomeMethod() { … } Допълнителна информацияПовече информация за езика, включително спецификацията му, можете да откриете на http://msdn.microsoft.com/vcsharp/ ADO.NET
Какво е ADO.NET?
ADO.NET представлява набор от библиотеки за работа с данни, включени в .NET Framework. Те включват класове, интерфейси, структури и други типове и са предназначени за достъп до различни източници на данни. Широко използвана доскоро Windows технология за достъп е ADO (ActiveX Data Objects). ADO.NET е неин наследник, и я разширява с много нови възможности, които се налагат от развитието на технологиите – например, съобразява се с изпълнението в Интернет среда, която налага да се използва достъп с непостоянна връзка (connectionless). ADO.NET е изцяло базиран на .NET Framework и притежава много от неговите характеристики – поддръжка на множество езици, автоматично управление на паметта, обектно-ориентиран дизайн, обща система от типове и конвенция за именуване. Предоставят се средства, които позволяват с данните да се работи независимо от какъв източник идват. Модели за работа с данни в ADO.NETПреди да се запознаем в детайли с технологията ADO.NET, ще
се спрем на моделите за достъп до данни, които се използват при изграждането на
информационни системи. В практиката се използват свързан модел с постоянна
връзка към базата данни и несвързан модел, при който връзката с базата данни не
е постоянна и се осъществява за кратко – само за зареждане на данните и
нанасяне на промените по тях. При реализацията на този модел, която предлага ADO.NET,
данните могат да бъдат четени само напред – връщане назад не е възможно.
Промени не могат да се правят докато данните се четат – за тази цел трябва да
се изпълняват отделни заявки към базата. Затова обикновено свързаният достъп се
използва, когато е необходимо да се прочетат данни или да се направи единична
промяна, но не се изисква сложна обработка на много информация от базата.
Свързаният модел работи директно със SQL заявки и е по-близък до релационните
бази от данни. Това прави производителността му много добра. При него се изискват
по-малко усилия от страна на разработчика. Съществено предимство на този подход
е, че по-лесно се контролира конкурентният достъп на много потребители до
данните в базата. Освен това вероятността да се работи с текущата версия на
данните е много по-голяма, отколкото при несвързания модел. Един от основните
недостатъци на свързания модел е необходимостта от постоянна мрежова връзка с
източника на данните. В някои случаи това може да се окаже проблемно и би
довело до голямо натоварване на мрежата. Това не е единственият проблем. При
много организации връзката между отдалечени офиси и централния сървър не е
надеждна и свързаността не е постоянна, поради което се налага offline работа. Друг
недостатък е заемането на ресурси (отворени връзки към базата) за продължително
време. Така при нарастване на броя потребители може да се окаже, че физическите
ресурси са недостатъчни да обслужат всички заявки. Проблемът е особено сериозен
при Интернет приложенията, където е възможно едновременно много голям брой
потребители да направят заявка към база от данни. При несвързания модел работата с данните се осъществява offline – данните се изтеглят от базата и се съхраняват на локалната машина. Първоначално се осъществява връзка към източника на данни, за да се извлече необходимото подмножество от данни. То се съхранява в локалната система и връзката се затваря. След това върху тях се извършва необходимата обработка. През това време няма връзка с базата (затова моделът се нарича несвързан). След извършване на нужните операции с данните връзката може да се отвори отново, за да се въведат направените промени и/или да се извлекат още данни. Основно предимство на несвързания модел е, че клиентът се свързва с основната база от данни само, когато има нужда. Това намалява натоварването на сървъра на базата от данни и изразходва по-малко ресурси. Често се случва приложението да трябва само да чете и визуализира данните. Тези операции могат да бъдат извършени и в несвързан режим, като при това не се заемат ресурси на сървъра и други потребители също могат да се свързват междувременно. Увеличаването на броя потребители не води до много по-голямо натоварване на базата от данни, защото ресурсите за обслужване на всеки потребител са необходими само докато трае неговата заявка и след това се освобождават. Недостатък на несвързания модел на достъп е, че данните при клиента не винаги са текущи. След изтегляне и прекъсване на връзката с базата, в нея данните могат да бъдат променени от други потребители, но тези промени няма да се отразят върху изтеглените данни. Така има опасност да се работи с остарели данни. Друг недостатък е, че трябва да се положат допълнителни усилия от разработчика за разрешаване на конфликтите между различните версии на данните. Подобен случай възниква, ако след запазване на данните на локалната машина потребителят промени някаква стойност в тях, а същевременно друг потребител промени същата стойност в основната база. Тогава, когато потребителят се опита да обнови данните в базата, настъпва конфликт. Пример: Нека да си
представим работата на една средно голяма фирма за търговия, около 100-200
души, които се намират в един офис. Те са свързани в единна фирмена мрежа. Сред
тях има дилъри, които се занимават с приемане на поръчки по телефона, складови
работници, които трябва да разберат за уговорените от дилърите сделки и да
приготвят стоката за изпращане или предаване на клиента, ръководители, които
трябва да знаят и следят процесите във фирмата чрез изготвени от софтуерния
продукт отчети. За такава фирма най-приложима е архитектурата на свързвания
модел. Предимството на този модел, че всяка една промяна се отразява и вижда
моментално от всички, е всъщност най-важното за такъв тип фирми. Без това, те
не биха могли да прилагат реално какъвто и да е софтуер. А какво става, ако
тази фирма има няколко офиса из страната? Отговорът е най-често в използването
на свързан модел за всеки отделен офис и създаването на допълнителен продукт, в
който посредством несвързан модел, през определено време, да се събират данните
от всички офиси и да се обединяват. Свързаният и
несвързаният модели не се изключват взаимно, а често се прилагат заедно. Как работи ADO.NET?
ADO.NET предлага програмен модел за работа с данните, който
съответства на двата модела за достъп до данни – свързан и несвързан. Освен
това обектният модел на ADO.NET предлага много фин контрол върху връзката с
източника, изпълнението на команди и обработката на данните. В ADO.NET се прави
ясно разграничаване между достъпа до данните и тяхната манипулация. Важна
характеристика на ADO.NET е възможността за работа в несвързана среда. В
ADO.NET тази възможност е вградена, а това улеснява разработката на многослойни
приложения и Web
услуги. ADO.NET се състои от компоненти за работа в свързана и несвързана среда, които могат да имат
имплементация за различни бази от данни. Диаграмата
по-долу изобразява основните компоненти на ADO.NET:
Най-отдолу
на диаграмата са различните видове бази данни, а над тях са съответните
доставчици на данни (Data Providers). Доставчиците на данни са съвкупности от
класове, които осъществяват връзка с различни бази от данни. Те осигуряват
възможност да се изпълняват команди и да се получават резултатите по начин,
който е независим от източника на данни и неговата специфична функционалност.
Доставчиците на данни са проектирани да осигуряват ефективен достъп за промяна
на данните или само за извличане. За различните системи с бази данни се
използват различни доставчици, като всеки е оптимизиран за работа със
съответната база. Най-отгоре са класовете, чрез които се осъществяват
свързаният и несвързаният модел. Тези класове предоставят общ интерфейс,
независещ от конкретния източник на информация. Връзката с него се осъществява
посредством съответния Data Provider. SQL конфигурация
Реализация на свързан
модел в ADO.NET
Свързан
модел имаме в случаите, когато данните се пазят на сървъра и клиентът е
постоянно свързан към него. При този архитектурен модел, за да изпълни своите
задачи клиентското приложение постоянно комуникира със сървъра. Като идеология и начин на действие в ADO.NET, свързаният
модел се имплементира чрез три основни класа – клас за отваряне
на връзка (SqlConnection), клас за изпълнение
на команда/команди (SqlCommand), клас за обработка
на редовете, получени като резултат от изпълнена заявка, който наричаме четец (SqlDataReader). Последователността от действия за изпълнение на команда към
сървъра са: 1. Отваряне на връзка. 2. Изпълнение на команда/команди. 3. Обработка на редовете, получени като резултат от заявката
чрез четец. 4. Затваряне на четеца. 5. Затваряне на връзката (ако няма да се изпълняват повече
команди). Пример: Създаване на таблица в базата данни. using
System; using
System.Data; using
System.Data.SqlClient; namespace
ConsoleApplication5 { class Program { private
const string
CONNECTION_STRING = "Server=.;" + "
Database=dbExample; Integrated Security=true"; private
const string
COMMAND_CREATE_TABLE = "CREATE
TABLE Users (" + "UserID int primary key, " + "FirstName nvarchar(50), " + "LastName nvarchar(50), " + ")"; static void Main() { SqlConnection
con = new SqlConnection(); con.ConnectionString =
CONNECTION_STRING; con.Open(); try { SqlCommand
command = new SqlCommand(); command.Connection = con; command.CommandText =
COMMAND_CREATE_TABLE; command.ExecuteNonQuery(); } finally { con.Close(); } } } } 1. Отваряне на
връзка. За осъществяване на връзката създаваме обекта con от тип SqlConnection. На
свойството ConnectionString на обекта присвояваме низ, който
съдържа информация за сървъра, към който ще се осъществява връзката, за базата
данни и за начина на автентикация. При извикване на метода Open(),
този низ се използва за правилното отваряне на връзката. При подходящо зададени
параметри и пуснат сървър връзката вече е осъществена. 2. Изпълнение на
команда. За изпълнение на команда имаме нужда от обект от тип SqlCommand. На
свойството Connection присвояваме отворената
вече връзка, а на свойството CommandText – низ, който
представлява команда на езика SQL.
Изпълняваме командата с извикване на метода ExecuteNonQuery(). 5. Затваряне на връзката. Връзката се затваря като се извика метода
Close(). След
извършването на всички операции връзката задължително трябва да се затвори, за
да освободи ресурсите на сървъра. За да сме сигурни, че връзката ще се затвори
дори и ако възникне изключителна ситуация, заграждаме кода си в try/catch блок и затварянето
правим във finally частта. Чрез инстанции на SqlCommand
се изпълнява обръщение към SQL заявка или съхранена процедура на сървъра. Съхранените
процедури се намират на SQL сървъра и работят локално с базата данни.
Обръщението става след като бъде осъществено свързването с базата от данни чрез
метода Open() на инстанцията на SqlConnection. ● По-важни свойства на SqlCommand Свойство Connection ни позволява да
зададем (или получим стойността на вече зададена) връзка, през която ще се
изпълнява командата. Макар, че е позволено да има повече от една връзка към
базата от данни от едно приложение, това не се препоръчва. Обикновено всички
команди се изпълняват през една и съща връзка. Изключение правят сървърните приложения,
които по принцип са предназначени да обслужват едновременно много потребители,
например Web услугите. За тях има обикновено по една
връзка за всеки обслужван в даден момент потребител. Свойство CommandType (тип команда) е изброимо и
може да приема като стойност три типа команди. Те указват съответно дали
командата ще бъде за изпълнение на съхранена процедура (тип StoredProcedure), за директна
работа с таблица (тип TableDirect) или е стандартен SQL текст (тип Text). Последният
тип е най-често използваният, като той може да замести предходните два. Чрез
него могат да се извикват и съхранени процедури и да се работи с една или
повече таблици. Свойството CommandText съдържа име на
съхранена процедура, име на таблица или текста на SQL заявка в зависимост от
споменатите типове команди. ● По-важни методи на SqlCommand Методът ExecuteScalar() на командата, връща единична стойност (първата
колона от първия ред от резултата). Този метод се ползва само в случаите,
когато искаме да получим единична стойност, върната при изпълнение на SQL
заявка или съхранена процедура. Върнатата стойност е от тип System.Object и трябва да се конвертира към съответния очакван
тип. Можем да използваме метода например за извикване на съхранена процедура,
която добавя нов запис в дадена таблица и връща неговия първичен ключ,
генериран от сървъра. За изпълнение на
SQL заявка и извличане на съвкупност от данни, се използва методът ExecuteReader() на SqlCommand. Той връща обект от класа SqlDataReader, който
предоставя курсор за навигация по върнатия резултат от изпълнената команда. ExecuteReader() се ползва в случаите, когато искаме да получим
съвкупност от редове и колони с данни, например при SELECT заявки. Чрез
незадължителния параметър CommandBehavior се задават
настройки на метода, от които се определя дали да се затвори връзката към
базата от данни след затваряне на DataReader обекта (CloseConnection), дали да се
върне само един ред (SingleRow) или само единична стойност (SingleResult) и др. По
подразбиране връзката към базата от данни не се затваря, а резултатът от
заявката се състои от множество редове и колони. Методът ExecuteNonQuery() се използва при изпълнение на заявки за промяна
на таблица (INSERT, UPDATE, DELETE). Той връща броя на засегнатите от
заявката записи. Типът на резултата е целочислен (int). Чрез инстанции
на SqlDataReader се осъществява обработката на получените записи
след изпълнение на команда (SqlCommand). Те са достъпни под формата на курсор,
който може да се преглежда в посока само напред (forward-only) и да се ползва
само за четене (read-only). Чрез този клас не могат да се правят
промени по данните, нито той може да се обхожда, сортира и т.н. Целта на SqlDataReader е да се получи резултат от SELECT заявка или съхранена процедура и да се обработят
данните, които са върнати, без да се променят. За промяна на данните в базата
данни се ползват команди (SqlCommand). ● По-важни методи и свойства на SqlDataReader Свойство Item (индексатор в C#) извлича, стойността на колона
по зададено име или индекс. Типът на върнатата стойност зависи от типа на извличаната
колона. Методът Read() придвижва
курсора напред и връща false, ако няма следващ
запис. Методът Close() затваря курсора.
Когато приключим работа с инстанцията на SqlDataReader, задължително трябва да затворим курсора.
В противен случай рискуваме да предизвикаме загуба на ресурси. Пример: Нека
вече има някакви данни в таблицата. Това е примерен код, който ги извежда: using System; using System.Data; using System.Data.SqlClient; namespace ConsoleApplication5 { class Program { private const
string CONNECTION_STRING = "Server=.; " +
"Database=dbExample; Integrated Security=true"; private const
string COMMAND_SELECT_AUTHORS = "SELECT
UserID, FirstName, LastName FROM Users"; static void
Main() {
SqlConnection con = new SqlConnection(CONNECTION_STRING); con.Open(); try {
SqlCommand command = new SqlCommand
SqlDataReader reader = command.ExecuteReader(); using
(reader) {
while (reader.Read()) {
int userID = (int)reader["UserID"];
string firstName = (string)reader["FirstName"];
string lastName = (string)reader["LastName"]; Console.WriteLine("User
{0} is {1} {2}",
userID, firstName, lastName); } } } finally {
con.Close(); } } } } В този пример
стойности на свойствата на връзката и командата се задават като параметри на
конструкторите им. Новото е използването на обект от тип SqlDataReader. Тъй
като изпълняваме SELECT команда, използваме метода ExecuteReader() на
командата. Този метод връща обект от тип SqlDataReader, затова създаваме такъв
обект. Докато методът Read() връща ред от таблицата, извеждаме на екрана
съдържанието на полетата. Обърнете внимание на конструкцията
using(reader){...}. След изпълнението на блока с код ще се извика метода
Dispose() на обекта reader. Този метод вътрешно вика метода Close() и затваря
четеца. По същият начин може да се процедира и с обекти от тип SqlConnection,
които също имат такъв метод. ADO.NET в несвързана среда
Най-характерното за несвързания модел е, че се работи с
копие на данните от базата, което се намира в паметта на локалната машина.
Докато данните се обработват локално, не се поддържа отворена връзка към
сървъра на базата от данни. Първоначално се отваря връзка към базата данни (SqlConnection) и част от данните се
зареждат и кешират в паметта в DataSet обект
и връзката се преустановява. След обработка на заредените данни в паметта, е
възможно повторно отваряне на връзка за внасяне на промените, които потребителят
е направил. Това става най-често с класа SqlDataAdapter. Работата с данни в несвързана среда може да се опише със
следната последователност от стъпки: 1. Отваряне на връзка. 2. Създаване и запълване на DataSet обект. 3. Затваряне на връзката. 4. Работа с DataSet обекта
(обработка на данните). 5. Отваряне на връзка. 6. Нанасяне на промените от DataSet обекта върху данните в базата от данни (и
разрешаване на конфликтите, когато има такива). 7. Затваряне на връзката.
Класът DataTable съхранява данните, подобно на таблица в базата от данни.
Той представлява кеширано копие на данните от таблица в паметта. Този клас има
важна роля в архитектурата на ADO.NET. DataTable може да се използва както самостоятелно, така и като част
от DataSet обекти. DataTable дава възможност за извършване на различни операции върху
данните, които съхранява. Данните могат да бъдат филтрирани, сортирани и
модифицирани. DataTable съдържа
три колекции – Columns, Rows и Constraints. Колекциите Columns и Constraints дефинират схемата на таблицата (колоните и ограниченията),
докато Rows съдържа самите данни. DataTable таблиците
не само съдържат в себе си съвкупност от редове със стойности, но и пазят
всички промени, направени по тях. Това много улеснява идентифицирането на
промените, които са извършени в дадена таблица от момента на нейното зареждане.
Всяка таблица поддържа списък от добавените, изтритите и променените редове в
нея. Този списък първоначално е празен. Той може да бъде извлечен по всяко
време с метода GetChanges(), а при нужда може да бъде
изтрит с метода AcceptChanges(). При актуализиране
на данните в базата извличаме променените записи с метода GetChanges() и извършваме съответни промени, като
разрешим евентуалните конфликти, които се получават. Накрая извикваме метода AcceptChanges(), за да анулираме списъка с промените по
таблицата, тъй като те вече са отразени в базата данни. SqlDataAdapter Нанасянето на промените в базата
данни и разрешаването на конфликтите, които могат да се получат, е задача,
която се извършва най-често посредством DataAdapter класовете. Класът DataAdapter осъществява връзката между DataSet обекта и източника на
данни. При работа с SQL сървър се използва наследникът
му SqlDataAdapter. ● DataAdapter дефинира
команди, чрез които извършва извличането на данните от източника и тяхното
обновяване. По-конкретно, за извличане на запис се използва командата SelectCommand, за добавяне на запис – InsertCommand, за промяна на запис – UpdateCommand и
за изтриване на запис – DeleteCommand.
Тези команди представляват SQL заявки, които извършват съответните действия. За
да работи правилно един DataAdapter,
освен командите, трябва да му се зададе и връзка към базата данни (Connection), през която да ги изпълнява. На фигурата е показана архитектурата на DataAdapter:
● Методът Fill() се използва за извличане на данни от източника на данни.
Чрез него може да се запълни DataSet обект
или самостоятелен DataTable обект.
При извикване на този метод се изпълнява заявката, която се съдържа в
свойството SelectCommand на DataAdapter обекта и данните се извличат в таблица от DataSet обекта или в DataTable обекта. ● DataAdapter сам се
грижи за връзката с източника – не е нужно ние явно да
я отваряме и затваряме. След приключване на работата си DataAdapter оставя връзката в състоянието, в което
я е получил. Пример: Кратка реализация на
несвързан модел: В този пример използваме SqlDataAdapter обект (adapter), за да осъществим връзката между базата данни и DataSet
обекта, в който пазим и обработваме данните (aSet). Обектът от тип SqlCommandBuilder е необходим, за да може по SELECT командата и по промените в данните да се създаде
подходяща UPDATE команда за промяна в базата данни (това става
автоматично, без нужда от намеса на програмиста). Примерът визуализира данните
преди и след промяната. using System; using System.Data; using System.Data.SqlClient; namespace ConsoleApplication5 { class Program { private
const string CONNECTION_STRING
= "Server=.; " + "Database=dbExample;
Integrated Security=true"; private
const string
COMMAND_SELECT_AUTHORS = "SELECT
UserID, FirstName, LastName FROM Users"; static void Main() { SqlConnection
aCon = new SqlConnection(CONNECTION_STRING); SqlDataAdapter
adapter = new SqlDataAdapter SqlCommandBuilder
aBuilder = new SqlCommandBuilder(); aBuilder.DataAdapter = adapter; DataSet
aSet = new
DataSet(); adapter.Fill(aSet,"Users"); Console.WriteLine("Съдържание на Users:"); foreach
(DataRow row in
aSet.Tables["Users"].Rows) { Console.WriteLine("{0} {1} {2}", row["UserID"], row["FirstName"],row["LastName"]); } aSet.Tables["Users"].Rows[2]["LastName"]
= "Petrov"; adapter.Update(aSet,"Users"); Console.WriteLine("Ново съдържание на Users:"); foreach
(DataRow row in
aSet.Tables["Users"].Rows) { Console.WriteLine("{0} {1} {2}", row["UserID"], row["FirstName"], row["LastName"]); } } } } По-подробен пример можете да изтеглите от тук. Използване на транзакции
Транзакциите са много важна възможност на модерните сървъри за управление
на бази от данни. Чрез тях се извършва изолация и синхронизация на достъпа до
данните от различни работни места, както и едновременното потвърждение (commit) или отказване (rollback) на поредица от заявки. ADO.NET предлага
множество функции за лесна програмна работа с транзакции. ● Основните възможности, които задължително се
налага да ползваме са започване на транзакция: SqlTransaction trans =
dbConnection.BeginTransaction(); въвличане на
команда в дадена транзакция: command.Transaction =
trans; потвърждаване на
транзакция: trans.Commit(); анулиране на транзакция: trans.Rollback(); При една транзакция или всички команди въвлечени в нея се
изпълняват (commit),
или, при възникване на проблем с някоя от тях, всички операции се отказват (rollback). ● Всяка транзакция има ниво на изолация,
което определя до каква степен можем да сме сигурни в достоверността на
данните, които се обработват по време на транзакцията. ADO.NET предоставя възможност за задаване
на ниво на изолация. Нивото на изолация се дефинира с изброения тип IsolationLevel на класа SqlTransaction. Типовете IsolationLevel са почти същите
като в SQL Server: с най-ниско ниво на изолация е Chaos – няма изолация; ReadUncommited – позволява
текущата транзакция да чете непотвърдени данни, добавени или променени от
други, паралелно изпълняващи се, транзакции, не осигурява повторяемост при
последователно четене на едни и същи данни и не предпазва от "фантомни
записи" (записи, които се появяват в дадена таблица по време на
транзакцията в резултат работата на друга, паралелна транзакция). Следват ReadCommited
и RepeatableRead.
С най-високо ниво на изолация е Serializable – заключва всички таблици, с които работи
текущата транзакция по такъв начин, че останалите, паралелно изпълняващи се
транзакции, да не могат да променят и добавят данни в тях докато текущата не
завърши. Осигурява повторяемост при четенето и защита от "фантомни
записи". Работа с XMLКакво е XML?
Съкращението XML идва от Extensible Markup Language, което подсказва, че XML е markup език с общо предназначение. Произходът на термина markup е свързан с областта на печатните издания, но при електронните документи markup описва специфичното обозначаване на части от документите с тагове. Таговете имат две основни предназначения – те описват изгледа и форматирането на текста или определят структурата и значението му (метаинформация). Днес се използват два основни класа markup езици – специализирани и с общо предназначение (generalized) markup езици. Първата група езици служат за генериране на код, който е специфичен за определено приложение или устройство и адресира точно определена необходимост – такъв език е HTML. Общите markup езици описват структурата и значението на документа, без да налагат условия по какъв начин ще се използва това описание. XML е типичен markup език с общо предназначение. Пример: Следният
пример демонстрира концепцията на markup езиците с общо предназначение. При тях
структурата на документа е ясно определена, таговете описват съдържанието си, а
форматирането и представянето на документа не е засегнато – всяко приложение
може да визуализира и обработва XML данните по подходящ за него начин. <?xml version="1.0" encoding="windows-1251"?> <messages> <message>XML markup описва структура и
съдържание</message> <message>XML markup не описва форматиране</message> </messages> Вместо тагове <message></message> можеше да
сложим <item></item>.
Структурата, обаче, не
се променя, което е същественото в случая. Добре дефинирани документиЕзикът XML дефинира понятието "добре дефинирани документи" (well-formed documents). Някои основни правила, които определят един XML документ като добре дефиниран, са следните: документът да има само един основен документен елемент, таговете винаги да се затварят и то в правилен ред (да не се преплитат), атрибутите винаги да се затварят по правилен начин, имената на таговете и атрибутите да отговарят на някои ограничения. Кога се използва XML?Езикът XML има изключително широка употреба в съвременните софтуерни технологии, защото предоставя универсален формат за съхранение и обмен на информация, а от това имат нужда болшинството от съвременните софтуерни системи. Обмяната на информация между системи, които боравят с несъвместими формати, е сериозно предизвикателство в съвременното информационно общество. Много системи работят с нестандартизирани, собствени формати и при нужда от взаимодействие разработчиците трябва да полагат много усилия, за да осигурят съвместимост на обменяните данни при комуникацията. XML е едно възможно решение на този проблем, тъй като позволява дефинирането на специфичен за приложението, прозрачен формат за обмяна на информация. XML документите, които спазват изискванията на езика, са разбираеми за всички приложения и така XML може да се използва като общ междинен формат при обмяната на информация. Съхранение на структурирани данни Почти всяко приложение има нужда от съхранение на данни. В много случаи XML е подходящ за тази задача, тъй като разделя структурираната информация от нейното визуално представяне. XML е подходящ формат за съхранение най-вече на малки информационни файлове или на данни, които не се очаква да поддържат произволно търсене (достъп). Тъй като XML е текстово базиран формат, запазването на по-големи структури от данни е свързано с голям обем на описанието им и този недостатък трябва да се има предвид. Правилно дефинирани (валидни) документиАко пишем приложение, което например ще си обменя информация
с някое друго посредством XML,
ще искаме XML
документите не само да са добре дефинирани, но и да отговарят на някакви
условия, свързани със съдържанието. Например ще искаме данните да съдържат кой
ги е създал или версията им или някаква друга предварително уговорена информация. За да се проверява дали даден XML документ има дадена
структура, можем да дефинираме друг XML документ (XML
схема), който да я определя. Схемите контролират структурата на XML документите
и дефинират необходимия синтаксис за целта. Схемите описват допустими тагове,
които могат да присъстват в един XML документ, допустими атрибути за тези
тагове, допустими стойности за елементите и атрибутите в документа, ред на
поставянето на таговете в XML документа, дефинират стойности по подразбиране.
Съществуват различни стандарти, които дефинират начина, по който се валидира XML документ. Най-популярните
от тях са DTD, XSD и XDR. XML и .NET
Framework
За разлика от много програмни езици и платформи, които
осигуряват средства за работа с XML под формата на добавки към основната
функционалност, .NET Framework е проектиран от самото начало с идеята за силно
интегрирана XML поддръжка. Имплементациите на основните XML технологии се
съдържат в асемблито System.Xml, където са дефинирани следните
главни пространства от имена: System.Xml –
осигурява основните входно-изходни операции с XML (XmlReader и XmlWriter);
System.Xml.Schema – осигурява поддръжка на
валидация на XML съдържание чрез XML схема (XmlSchemaObject и
наследниците му); System.Xml.XPath –
реализира функционалност за XPath търсене на информация и навигация в XML
документ (класовете XPathDocument,
XPathNavigator и XPathExpression); System.Xml.Xsl –
предоставя възможност за трансформации на XML документи (XslTransform); System.Xml.Serialization –
осигурява сериализация до XML и SOAP (XmlSerializer).
При работата с бази данни много полезен е класът System.Xml.XmlDataDocument, който предоставя средства за представяне
на таблични данни в йерархичен вид. Този клас се използва за синхронизация на DataSet и XML документ и позволява да работим
едновременно с двете представяния на едни и същи данни. Windows Forms
Какво е Windows Forms?
Повечето софтуерни продукти имат нужда да комуникират с потребителя по някакъв начин. Основно това взаимодействие се получава посредством бутони, полета, форми, и др. Дизайнът на потребителския интерфейс е много важна част от модерните графични приложения, понеже външният вид на приложението е това, с което клиентите работят. В миналото Visual Basic 6.0 поставя началото на така нареченото графично програмиране, като иновационното е графичният начин, по който се поставят контролите върху формите. (Контроли са всички бутони, форми, полета, радио бутони, check box-ове, и други.) Програмистът е трябвало първо да оформи потребителския интерфейс и след това да зададе функционалността на поставените от него контроли, пишейки код. Проблем се оказа тромавият синтаксис на самия език Visual Basic, който значително се различава от този на езиците C/C++, които са основните използвани по това време. Това довежда до ситуацията, в която опитен програмист, на който му се налага да направи приложение на Visual Basic, трябва да губи часове, защото по инерция е поставил знака ‘;’ на края на реда. С излизането на .NET Framework се обособява и Windows Forms Framework. Така вече е възможно да се възползваме от простотата, която ни дават Windows Forms и възможността да използваме всеки от езиците, които Common Language Runtime (CLR) поддържа. Windows Forms Framework ни предоставя ясна, обектно-ориентирана група от класове, която ни позволява да разработваме мощни приложения за Windows. Формата е парче от екрана, обикновено правоъгълно, върху което можете да показвате информация на потребителя и да приемате данни от него. Формите могат да бъдат стандартни Windows прозорци, диалогови полета, или площи където се изобразяват графики. Всяка форма се състои от опции, които определят външния й вид, методи, които определят поведението й, и събития, които определят взаимодействието й с потребителя. Сега нека разгледаме някои примери, за да вникнем в същността на Windows Forms. Въпреки че всички форми могат да бъдат създадени изцяло чрез писане на код, далеч по-лесно е да използвате Windows Forms Designer. Windows Forms Designer
В тази глава на статията ще поставим акцента на това, как лесно и бързо да създаваме приложения, които ползват Windows Forms с помощта на Visual Studio 2005. Нека сега създадем някое просто приложение. Отворете VS2005 и създайте нов проект на езика C# от тип Windows Application. Когато създаването приключи трябва да получите следното:
С това приключва работата по дизайна на вашето малко приложение и сега следва да реализираме функционалността му. За целта трябва да укажем какво се случва, когато потребителят натисне бутона. Ако във VS2005 натиснем два пъти бутона, ще се отвори поле, където да поставим кода, който ще се изпълни при натискане на бутона. Кодът е следният: private void button1_Click(object sender, EventArgs e) { string str; str = textBox1.Text; textBox1.Text = str + " e SUPER"; } Сега приложението, при натискането на бутона, ще добавя текста " e SUPER" към вече въведеното в текстовото поле. Така, ако въведем текста “Pesho” и натиснем бутона ще получим “Pesho e SUPER”.
Добавете от Toolbox–а контролата WebBrowser към формата и за красота добавете контролата Label между бутона и текстовото поле. В панела Properties (който по подразбиране е долу в дясно) променете свойството му text на “Address”. Сменете същото свойство на бутона на “Go”. На картинката в дясно се вижда как изглежда приложението сега. Остава да направим и промяна по кода на процедурата, която
отговаря на събитието натискане на бутона: private void button1_Click(object sender, EventArgs e) { webBrowser1.Url = new
Uri(textBox1.Text); } Единственото по-сложно горе е
прехода от типа на textBox1.Text към типа на webBrowser1.Url. Сега можете да стартирате приложението и сами да
се обедите колко лесно създадохме макар и бегло подобие на браузър.
|