INTRODUCERE ………………………….. ………………………….. ………………………….. …………………… 1 1…. [614176]
UNIVER SITATEA DIN PITEȘTI
FACULTATEA DE MATEMATICĂ -INFORMATICĂ
Specializarea : Informatică
LUCRARE DE LICENȚĂ
Coordonator științific :
Lect. Univ. Dr. Doru Anastasiu
POPESCU Absolvent: [anonimizat]
2015
UNIVERSITATEA DIN PITEȘTI
FACULTATEA DE MATEMATICĂ -INFORMATICĂ
Specializarea : Informatică
Reinvestirea profitului unei
firme în baza materială
Coordonator științific :
Lect. Univ. Dr. Doru Anastasiu
POPESCU Absolvent: [anonimizat]
2015
Cuprins
INTRODUCERE ………………………….. ………………………….. ………………………….. …………………… 1
1. TEHNOLOGII FOLOSI TE ………………………….. ………………………….. ………………………….. ….. 2
1.1. ARHITECTURA .NET ………………………….. ………………………….. ………………………….. ……….. 2
1.1.1. Framework -ul .NET ………………………….. ………………………….. ………………………….. ………………… 2
1.1.2. Compone nte ale lui .NET Framework și arhitectura acestuia ………………………….. ……………….. 3
1.1.3 . Compilarea programelor ………………………….. ………………………….. ………………………….. ………… 6
1.1.4 . De ce am alege .NET? ………………………….. ………………………….. ………………………….. ………….. 7
1.2. INTRODUCERE ÎN LIMBAJ UL C# ………………………….. ………………………….. ……………………… 8
1.2.1. Caracteriza re ………………………….. ………………………….. ………………………….. ……………………….. 8
1.2.2. Structura unui program C# ………………………….. ………………………….. ………………………….. ……… 9
1.2.3 . Tratarea excepțiilor în C# ………………………….. ………………………….. ………………………….. ……….. 9
1.3. PRINCIPIILE PROGRAMĂR II ORIENTATE PE OBIE CT ………………………….. ……………………….. 13
1.3.1. Principiile programării orientate pe obiect ………………………….. ………………………….. ………….. 13
1.3.2 . Moștenirea ………………………….. ………………………….. ………………………….. ………………………… 14
1.3.3 . Polimorfism ………………………….. ………………………….. ………………………….. ……………………….. 15
1.4. ADO.NET ………………………….. ………………………….. ………………………….. …………………. 17
1.4.1 . Arhitectura ADO.NET ………………………….. ………………………….. ………………………….. …………. 17
1.4.2 . Furnizori de date în ADO.NET ………………………….. ………………………….. ………………………….. 19
1.4.3 . Connection ………………………….. ………………………….. ………………………….. ………………………… 20
1.4.4 . Command ………………………….. ………………………….. ………………………….. …………………………. 22
1.4.5 . DataReader ………………………….. ………………………….. ………………………….. ……………………….. 23
1.4.6 . DataAdapter ………………………….. ………………………….. ………………………….. ……………………….. 24
1.5. TEHNOLOGII SMTP(S IMPLE MAIL TRANSFER PROTOCOL ) ………………………….. …………….. 26
1.5.1. Ce este SMTP? ………………………….. ………………………….. ………………………….. …………………. 26
1.5.2. Clasa MailAddress ………………………….. ………………………….. ………………………….. ……………… 26
1.5.3 . Clasa SmtpClient ………………………….. ………………………….. ………………………….. ……………….. 27
1.5.4 . Clasa MailMessage ………………………….. ………………………….. ………………………….. ……………. 28
1.6. ALGORITMI ………………………….. ………………………….. ………………………….. ………………… 29
1.6.1. Algoritmul Greedy ………………………….. ………………………….. ………………………….. ………………. 29
2. FUNDAMENTE – SQL SERVER ………………………….. ………………………….. …………………….. 31
2.1. SQL SERVER ………………………….. ………………………….. ………………………….. ………………. 31
2.1.1 . Scurtă introducere ………………………….. ………………………….. ………………………….. ……………… 31
2.1.2. Modelarea datelor ………………………….. ………………………….. ………………………….. ………………. 33
2.1.3 . Normalizarea bazelor de date ………………………….. ………………………….. ………………………….. . 36
2.1.4 . Securitatea aplicațiilor cu baze de date ………………………….. ………………………….. ……………… 37
3. APLICAȚIE: DEZVOL TAREA APLICATIVĂ ………………………….. ………………………….. …….. 38
3.1. DESCRIEREA APLICAȚIEI ………………………….. ………………………….. ………………………….. … 38
3.1.1 . Motivul aplicației ………………………….. ………………………….. ………………………….. ………………… 38
3.2. PAGINILE APLICAȚIEI ………………………….. ………………………….. ………………………….. …….. 39
3.2.1 . Logarea în aplicație ………………………….. ………………………….. ………………………….. ……………. 39
3.2.2 . Cautarea și introducerea datelor ………………………….. ………………………….. ………………………. 41
3.2.3 . Fereastra Calculator ………………………….. ………………………….. ………………………….. …………… 44
3.2.4 . Fereastra Export Date ………………………….. ………………………….. ………………………….. ………… 47
3.2.5 . Fereastra Ajutor ………………………….. ………………………….. ………………………….. …………………. 49
3.3. CLASA PRINCIPALĂ ”STARE ” ȘI CLASELE DERIVATE ALE ACESTEIA ………………………….. ……. 50
3.3.1 . Stare – Clasa abstractă principală ………………………….. ………………………….. …………………….. 50
3.3.2 . Starea1Autentificare – Clasa aferentă ferestrei Autentificare ………………………….. ……………. 50
3.3.3 . Starea2Calculator – Clasa aferentă ferestrei Calculator ………………………….. …………………… 51
3.3.4 . Starea3ExportDate – Clasa aferentă clasei Export Date ………………………….. ………………….. 51
3.3.5 . Starea4Ajutor – Clasa aferentă ferestrei Ajutor ………………………….. ………………………….. …… 52
3.3.6 . Starea5Iesire – Clasa destinată ieșirii din aplicație ………………………….. ………………………….. 52
3.3.7. Stare6Cautare – Clasa aferentă ferestrei Cautare ………………………….. ………………………….. . 53
3.3.8 . Exemplu ………………………….. ………………………….. ………………………….. ………………………….. .. 53
BIBLIOGRAFIE ………………………….. ………………………….. ………………………….. …………………… 56
ANEXE ………………………….. ………………………….. ………………………….. ………………………….. … 557
1
Introducere
Această lucrare reprezintă proiectul meu de licentă în cadrul Universității din Piteșt, al
facultății de Matematica -Informatică.
În cadrul facultății am învățat să pun în practică cunoștințele dobândite în cei trei ani de
facultate, dar și lucruri noi sau de aprofundare.
În primul capitol al lucrării am prezentat caracteristicile introductive ale lucrării,
tehnologiile folosite în cadrul lucrării precum: arhitectura platformei .NET, o scurtă introducere
în limbajul C#, principiile programării orientate pe obiect folosit în cadrul aplicației, a rhitectura
ADO.NET, tehnologii SMP, algoritmi folositi, dar și mijloacele folosite la realizarea aplicației.
În cel de -al doilea capitol am discutat despre SQL Server, un program de baze de date
cât și despre modelarea datelor si normalizarea acesteia.
sunt prezentate pe scurt urmatoarele concepte:
Al treilea capitol reprezintă un manual de utilizare, în care sunt descrise acțiunile
utilizatorului în cadrul folosiriii aplicației, sunt detaliate aspecte privind dezvoltarea și
organizarea aplicației, cea mai importantă secțiune fiind modul de calculare și selectie al
produselor. Tot în acest capitol se face o analiză a modului de structurare a datelor folosite de
aplicație, precum și o analiză a modului de concepere a aplicației, prezentând problemele de
implementare, principalele funcționalitățti ale aplicației și cele mai importante părți din codul
aplicației.
2
Capitolul 1.
Tehnologii folosite
1.1. Arhitectura .NET
1.1.1. Framework -ul .NET
Tehnologia .NET pune la dispoziție cele mai noi tehnologii precum: ASP, XML, OOP,
SOAP, WDSL, UDDI și limbaje le de programare: VB, C++, C#, J#, toate aceste tehnologii
asigurând, totodată, portabilitatea codului compilat între diferite calc ulatoare cu sisteme
Windows, dar totodată permite și reutilizarea codului în programe, indiferent de limbajul de
programare u tilizat.
.NET Framework este o componentă integrată pe sistemele de operare Windows care
sprijină dezvoltarea și executarea următoarelor generații de aplicații. Ultima versiune .NET
Framework 4.6 RC a fost lansată pe 12 noiembrie 2014, ea vine instalată pe Windows 10 și poate
fi instalată pe versiunile Windows 8.1, Windows 8, Windows 7 SP1 și Windows Vista SP2.
Platforma .NET constă în cateva grupe de produse:
1. Unelte de dezvoltare:
o mare parte din limbajele de programare care pot fi dezvoltate pe
platforma .NET sunt: C#, Visual Basic .NET, Managed C++, Smalltalk,
Perl, F ortran, Cobol, Lisp, Pascal, etc.
ca și medii de dezvoltare pe platforma .NET putem enumera: Visual
Studio .NET, Visio și multe altele.
.NET deține o bibliotecă impresionantă de clase pentru crearea serviciilor
Web, cât și pentru crearea aplicațiilor Windows desktop și Web.
2. Servere specializate − un set de servere Enterprice .NET pe care compania
Microsoft le pune la dispozitie utilizatorilor sunt : SQL Server 2014, SQL Server
2012, SQL Server 2008 R2, Exchange 2007, BizTalk Server 2006, SharePoint,
etc, toate aceste servere au rolul de apune la dispoziție utilizatorului
funcționalități diverse, atât pentru stocarea bazelor de date, cât și email, aplicații
B2B ( Bussiness to Bussiness – comerț e lectronic între partenerii unei afaceri).
3. Servicii Web – în marea majoritate a aplicațiilor care necesită identificarea
utilizatorilor serviciile web au o utilitate foarte mare. Spre exemplu, .NET
Passport folosește un singur nume de utilizator precum și o singură parolă prin
care utilizatorii se pot autentifica pe toate site -urile Web vizitate.
3
4. Dispozitive – dispozitive le non -PC programabile prin .NET Compact Framework,
au puse la dispoziție următoarele servicii: Pocket PC Phone Edition, Smartphone,
Tablet PC, Smart Display, Xbox, etc.
1.1.2 . Componente ale lui .NET Framework și arhitectura acestuia
Figura 1.1. Arhitectura .NET Framework 4.5
Componenta .Net Framework este formată din compilatoare, biblioteci și alte executabile
utile în rularea aplicațiilor .NET. Figura 1.1. schematizea ză arhitectura platformei .NET
Framework 4.5 care cuprinde cateva din următoarele componente:
Common Languag e Runtime (CLR) – Această componentă ca un motor de
execuție pentru .NET Framework, toate programele fiind executate sub controlul
CLR, totodată fiind cea mai importanta componentă a lui .NET Framework. CLR are
rolul de a se ocupa de managementul și execuț ia codului scris în limbaje .NET, aflat
în format CIL (Common Intermediate language) ; ca și asemănare CLR se aseamănă
foarte mult cu Java Virtual Machine.
4
Ca și funcționalitate CLR se ocupă cu:
– instanțierea obiectelor,
– verificări de securitate,
– depunerea obiectelor în memorie,
– disponibilizează memoria prin garbage collection.
Base Class Library – este o bibliotecă de funcții care sunt disponibile pentru toate
limbile care folosesc .NET Framework. Este compusă din clase, tipuri de interfețe
reutilizabile care se integrează cu CLR .
Portable Class Library – proiectul Portable Class Library din Visual Studio 2012
permite utilizatorului să dezvolte și să construiască ansambluri gestionate care
lucrează pe multiple platforme .NET Framework. Folosirea unui proiect de tipul
Portable Class Library permite utilizat orului de a opta spre platforme precum:
Windows Phone și .NET pentru aplicații Windows Store.
Managed Extensibility Framework (MEF) – MEF este o bibliotecă pentru crearea
de aplicații ușoare și extensibile. Aceasta permite dezvoltatorilor de aplicații să
descopere și să folosească extensiile făra nicio configurare
Dynamic Language Runtime – aceasta oferă mediul de rulare pentru limbajele
dinamice, cum ar fi Python, etc. pentru ca acestea să fie executate sub controlul
complet al CLR.
WinRT – WinRT sau W indows Runtime API furniează elementele de interfață ale
utilizatorului pentru construirea de aplicații Windows Store, și oferă aces la Windows
8 sau caracteristicile OS ale Windows RT. WinRT sprijină dezvoltarea în C și în alte
limbaje gestionate C# și VB .NET precum și JavaScript.
Asp.Net – este o tehnologie Microsoft folosita pentru a construi aplicații web bogate
pe internet. Asp.Net este succesorul lui ASP (Active Server Pages) și beneficiază de
puterea platformei de dezvoltare .NET, și de setul de ins trumente oferite de mediul de
dezvoltare al aplicației Visual Studio .NET.
Windows Store Apps (Metro Style Apps) – o aplicație Windows Store este un nou
tip de aplicație care rulează pe dispozitivele Windows 8 și pot profita de noile
5
avantaje ale API -ului WinRT, acestea putând fi distribuite numai în Windows 8
Store.
Desktop Apps (Windows Forms) – o aplicașie Desktop este tradișionala aplicație
Windows Forms cu un nume nou. Softurile dezvoltate pentru Windows Xp, Windows
Vista și Windows 7 vor fi clasific ate ca aplicație Desktop la rularea acestora pe
Windows 8. Ca și ecemplu de de aplicații Desktop produsele din familia Microsoft
Office, Notpad și multe altele.
WPF – este folosit pentru a crea aplicații cu o experiență de utilizare bogată. Aceasta
includ e aplicații UI, de grafică 2D respectiv 3D. Aceasta profită în special de
acelerarea hardware a cardurilor grafice moderne.
Silver Light – este o tehnologie bazată pe web cross -browser care permite
designerilor si dezvoltatorilor să ofere aplicații internet bogate (Rich Internet
Applications) încorporate în paginile Web.
Ado.Net – este folosit pentru a crea un Data Acces Layer pentru a interoga și
manipula date care stau la baza surselor de date precum SQL Server, Oracle, etc.
LINQ – permite interogarea datelor din diferite surse de date (cum ar fi baze de date
SQL, documente XML, seturi de date Ado.Net, diverse servicii Web, precum și orice
alte obiecte, cum ar fi Collections, Generics, etc.) folosind o interogare SQL ca
sintaxă cu limbajele .NET Framework ca C# și VB.
Ado.Net Entity Framework – este folosit pentru a interoga și stoca date în bazele de
date relaționle (cum ar fi SQL Server, Oracle, etc.).
Parallel Extension – permite să distribuiți codul dumneavoastră de muncă în mai
multe procesoare pentru a profita de hardware.
WCF – este folosit pentru construirea și dezvoltarea serviciilor bazate pe WS.
Asp.Net WebAPI – este un cadru pentru construirea serviciilor HTTP care pot fi
consumate printr -o gamă largă de clienți, inclusiv browsere, telefoane mobile, și
tablete.
SignalR – ASP.NET SignalR este o bibliotecă care simplifică procesul de adăugare al
funcționalității web în timp real pentru aplicații.
6
WF – este folosit pentru a construi fluxuri de lucru în procese orientate spre afaceri.
Common Language Specification (CLS) – este utilizat pentru a definii un ansamblu
de reguli pentru compilatoarele .NET Framework, el având rolul de a asigura că
fiecare compilator va genera cod care să interfereze cu platforma, mai exact cu CLR –
ul.
Visual Studio 2012 – Visual Studio IDE oferă un set de instrumente care vă ajută să
scrieți și modifica codul pentru programele dumneavoastră, si de a detecta și corecta
erorile din programele dumneavoastră. Folosind Visual Studio 2012 se poate construi
aplicații pentru Windows Store, aplicații desktop, aplicații mobile, aplicații web, și
servicii web.
Common Type System (CTS): CTS asigură cooperarea dintre limbajele specifice
platformei .NET, astfel încât o clasă scrisă in limbajul C# tr ebuie să fie echivalentă
cu una scrisă in VB.NET, similar și pentru iterfețe ele trebuind să fie perfect
utilizabile . Astfel spus toate limba jele trebuie să recunoască și să poată manipula un
set de tipuri comune ca: Tipuri valoare, Tipuri referință, Boxin g și unboxin, clase,
indexatori, proprietăți, interfețe, delegați.
1.1.3 . Compilarea programelor
Scrierea unui program într-unul dintre limbajele .NET cum ar fi Visual Basic sau C# și
compilarea acestuia conform Common Language Specification (CLS) va duce la traducerea
codului într -un limbaj independent numit Microsoft Intermediate Language (MSIL sau IL). La
momentul execuției, MSIL rulează în contextul .NET framework, care va traduce MSIL în
instrucțiuni specifice procesorului (CPU) pe care rulează ap licația. Astfel va fi generat codul cu
extensia ”exe” care nu va fi direct executabil, dar care va respectă formatul unic MSIL.
Codurile MSIL obținute în urma compilării vor fi introduse într -o mașină virtuală
asemănătoare cu o mașină Java care o vom regăsi inclusă în CLR . Mașina folosește un
compilator special JIT ( Just in Time ). Codul MSIL introdus în compilatorul JIT la urmal lui va fi
compilat și analizat astfel va fi produs codul mașină adecvat și eficient. Datorită acestor metode
de compilare pe parcursul rulării, aplicațiile .NET devin din ce în ce mai rapide deoarece codul
compilat poate fi reutilizat fară ca acesta să necesite o recompilare.
Cât despre CLR putem spune ca acesta se mai ocupă si cu diverse activități precum
gestionarea automată a memoriei.
7
Ca și portabilitate .NET Framework stă la baza unui standard numit CLI ( Common
Language Infrastructure ) care permite rularea aplicațiilor în afara platformelor Windows, și pe
platforme ca Unix, Linux, Solaris, Mac OS X și alte sisteme de operare .
1.1.4 . De ce am alege .NET?
Unul dintre motivele pentru care am alege .NET ar fi varietatea de instrumente pe care un
dezvoltator le poate utiliza și în alte programe, accesul la baze de date fiind foarte usor.
.NET Framework posedă o bibliotecă ce cup rinde peste 400 de clase structurate într -o
ierarhie de clase care are ca rădăcină o clasă Object.
Datorită numărului mare de denumiri pe care le presupune biblioteca FCL a fost nevoie
de gruparea claselor în spații de nume. Spațiile de nume sunt identific abile printr -un nume
propriu și ele conțin listele de denumiri de clase care aparțin acelui spațiu.
Spațiul de nume System.Windows.Forms conține instrumente (controale) ce permit
implementarea elementelor interfeței grafice cu utilizatorul. Folosind aceste controale, puteți
proiecta și dezvolta rapid și interactiv, elementele interfeței grafice. Tot .NET pune la dispoziție
clase care efectuează majoritatea sarcinilor uzuale cu care se confruntă programele, reducând
astfel timpul necesar dezvoltării aplicațiilor.
Avamtajele folosirii platformei .NET:
– Posibilitateta de dezvoltare de aplicații multilimbaj.
– Independența programelor de procesor și SO.
– Managementul automat al memoriei.
– Suport pentru versiuni.
– Distribuir facilă a aplicațiilor la beneficiar.
– Posibilitatea de utilizare de cod neadministrat(unmanaged).
– Înregistrarea descentralizată a componentelor.
Platforma .Net oferă o gamă variată de opțiuni pentru dezvoltatori și le asiură acestora o
serie de facilități care nu se regăsesc în alte medii de dezvoltare. Astfel de la clasele disponibile,
recunoașterea componentelor scrise în limbaje diferite până la managementul automat al
memoriei răspândirea .NET este pe deplin motivată.
8
1.2. Introducere în limbajul C#
1.2.1.Caracterizare
Microsoft este o companie americană, cea mai mare producătoare de software care a fost
fondată în data de 4 aprilie 1975 de către Bill Gates și Paul Allen. C# este unul din limbajele
dezvoltat de această companie din echipa de de ingineri care au dezvoltat acest limbaj regăsindu –
se și Anders Hejlsberg (autorul limbajului Turbo Pascal și membru al echipei care a proiectat
Borland Delphi).
Inginerii de la Microsoft care s -au ocupat de dezvoltarea acestui limbaj au ajuns la un
număr impresionant de cuvinte che ie folosite și anume 80 de cuvinte cheie precum și 12 tipuri de
date predefinite. C# a fost dezvoltat astfel încât să fie un limbaj ușor de învățat, dezvoltatorii
încercând să creeze o sintaxă cât mai asemănătoare limbajelor ca: C, C++ și Java astfel încât
sintaxa slimbajului să fie usor de recunoscut si de familiarizat cu ea.
Limbajul C# a fost construi conform concepelor moderne ale programării profesioniste
astfel este permisă programarea structurată, modulară și orientată obiectual, câteva din
elemente le fundamentale ale programării orientată pe obiecte fiind: încapsularea, moștenirea și
polimorfismul, aceste elemente fiind unu mariile principii fundamentale ale programării în C#.
Sintaxa limbajului C# simplifică multe din complexitatea C++ și oferă car acteristici
puternice, cum ar fi tipurile de valoare nulă, delegări, expresii lambda și acces direct la mem orie,
care nu se gasesc în Java, unele func ții fiind diversificate (tipul struct ) , modificate (tipul string )
sau chiar eliminate (moștenirea multiplă și pointerii către funcții) toate acestea având ca scop
realizarea unor secvențe de cod sigure ( safe).
În plus față de toate aceste principii orientate pe obiecte, C# facilitează dezvoltarea
componentelor software prin construirea mai multor limbi inovatoare , precum următoarele:
Semnături de metode incapsulate numite de delegari, care permit notificări de
evenimente de tip sigur ( safe).
Proprietăți, care servesc drept accesorii pentru variabilele membre private.
Atribute, care oferă metadate declar ative despre tipurile de la momentul execușiei.
Documente XML comentate în linie.
Limbajul integrat Query (LINQ), care ofera posibilitatea de interogare “built -in” pe o
varietate de surse de date.
9
1.2.2 .Structura unui program C#
Structura unui program C# în general este formată din spațiile de nume urmată de una
sau mai multe clase , care sunt grupate în spații de nume (namespace), metoda (funcția) Main
fiind obligatoriu să apară în cel puțin o singură clasă ea fiind numită “punct de intrare” (entry
point) .
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HelloWorld
{
class Program
{
static void Main(string[] args)
{
}
}
}
Clasa (class) , în termeni simplificați, reprezintă tipul referintă, care poate să moștenească
o singură clasă și poate implementa mai multe interfețe. Clasele reprezintă principalul element
structural și de organizare în limbjele orientate pe obiecte, grupând date cât ș i funcții care
prelucrează respectivele date, fiecare membru putând conține un nivel de protecție, care
controlează gradul de acces la el.
Spațiul de nume (Namespace) , este folosit pentru a declara un domeniu de aplicare care
conține un set de obiecte lega te. În general este utilizat pentru a organiza elementele de cod și de
a crea tipuri globale unice. În C# datorită spațiilor de nume există posibilitatea de a avea într -un
program definiții cu nume identic, dar situate în alte spații de nume. În cazul în c are, într -o
aplicație, unele clase sunt deja definite, ele se pot folosi importând spațiile de nume care conțin
definițiile acestora.
1.2.3 .Tratarea excepțiilor în C#
Tratarea erorilor și a situațiilor deosebite prin excepții se regăseste în multe limbaje de
programare printre care și C# . În general excepțiile sunt obiecte care încapsulează informații
despre o situație anormală, și sunt folosite de cele mai multe orie pentru a informa dezvoltatorul
conextul în care programul î ntâmpina o situație specială.
Atunci când este întalnită o sitație deosebită cu ajutoru instrucțiunii throw se va ”arunca”
o excepție care va trebui sesizată și tratată. Prinderea unei excepții și tratarea acesteia se face cu
10
ajutorul blocului catch . C# permite existența mai multor blocuri catch , fiecare dintre are având
rolul de a prinde și trata o excepție.
Pentru a garanta că un anumit cod se va executa indiferent daca totul decurge normal sau
apare o excepție, acest cod se va pune în blocul final ly care s e va executa în orice situație.
Tratarea excepțiilor nu trebuie confundată cu erorile sau bug -urile, u n bug reprezentând o
eroare de programare pe care dezvoltatorul/programatorul trebui să o fixeze . Cu toate ca apariția
unui bug în program poate provoca apariția unei excepții ele nu sunt gan dite pentru a preveni
bug-urile.
Chiar dacă programatorul elimină toate bug -urile din programul său pot apărea erori pe
care el nu le poate preveni:
încercarea de deschidere a unui fișier inexistent
împărțiri la zero
etc.
În cazul în care o metodă întalneșste o astfel de excepție, atunci respectiva excepție va
trebui ” prinsă ” în vederea tratării (rezolvării) ei.
Tipul Exception
În limbajul de programare C# tipul Exception permite arunca rea ca excepții obiecte de
tip System.Exception sau derivate ale lui. Pe lângă sistemul de clasificare a excepții lor pe care
limbajul C# îl are inclus, programatorul își poate crea propriile sale tipuri excepție.
Figura 1.2 . Ierarhia excepțiilor
11
Enumerăm câteva din metodele și proprietățile relevante ale clase Exception ar fi:
public Exception(), public Exception(string), public Exception(string, Exception) –
constructori; ultimul constructor preia un obiect de tip Exception care la urma lui va fi
încapsulat în instanța curentă; astfel spus o excepție poate deci să conțină o instanță a
altei excepții.
public virtual string HelpLink {get; set;} are rolul de a obține sau de a stabili o
legatură către un fisier help asociat acestei excepții; spre exemplu adresa URL a unei
pagini Web.
public Exception InnerException {get;} are scopul de a returna retur nează excepți a
care se află în interiorul excepției curentă.
public virtual string Message {get;} are scopul de a returna un mesaj care descrie
excepția curentă .
public virtual string Source {get; set; } are rolul de a obține sau de a seta numele
aplicației /programului sau al obiectului care a cauzat eroarea .
public virtual string StackTrace {get;} va returna o reprezentare de tip string a
apelurilor de metode care cauzat apariția acestei excepții.
Public MethodBase TargetSite {get;} va obține metoda care a aruncat excepția
curentă.
Blocuriel try și catch
Programarea orientată pe obiecte pune la dispoziție o soluție pentru gestionarea erorilor:
folosilea blocurilor try și catch . În scrierea codului unei aplicații , programatorul are rolul de a
separa instrucțiuni care nu pot fi generatoare de excepții, de cele care pot conduce la erori.
Pentru a putea trata o excepție codul de program care poate gen era excepții va fi plasa t într-un
bloc try, pe când partea corespunzătoare tratării excepției, va fi plasată într-un bloc catch.
Atunci când blocul try generează o excepție, Runtime va întrerupe execuția programului
și va începe să cautecel mai apropriat bloc catch , astfel încât să se poată trata respectiva eroare.
Când blocul catch va fi găasit programul va continua cu instrucțiunile aflate în interiorul
blocului catch , negăsirea unui bloc catch corespunzător care să poate trata respectiva eroare,
execuț ia porgramului va fi întreruptă.
12
Instrucțiunea throw
Această instrucțiune este folosita pentru ai oferi programatorului posibilitatea să -și
compună modalități proprii de aruncare a erorilor. Exemplu:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HelloWorld
{
class Program
{
static void Test()
{
try
{
Console.Write("Introduceti primul numar:" );
int a = int.Parse(Console.ReadLine());
Console.Write("Introduceti al doilea numar:" );
int b = int.Parse(Console.ReadLine());
int suma = a + b;
if (suma >= 0)
{
string exceptie = "suma numarelor este pozitiva!" ;
throw new ArgumentOutOfRangeException (exceptie);
}
}
catch (ArgumentOutOfRangeException )
{
Console.WriteLine( "Suma numerelor nu este pozitiva" )
}
}
static void Main(string[] args)
{
Test();
}
}
}
Atunci când o excepție este aruncată execuția metode este oprită, urmând ca CLR să
înceapă căutarea unui maipulator de excepție.
Dacă un handler de excepție nu este gasit în metoda curentă, atunci CLR ca curăța stiva,
ajungându -se la metoda apelantă. Fie undeva în lanțul de metode care au fost apelate se găsește
un excepțion handler, fie thread -ul curent este terminat de către CLR.
13
Instrucțiunea finally
Datorită inginerilor carea au dezvoltat limbajul C# este posibilă executarea anumitor
instrucțiuni, în cazul în care programatorul droește acest lucru, astfel aceste instrucțiuni vor fi
executate obligatoriu la ieșirea din blocul try. Pentru ca acest lucru sa fie posibil și instrucțiunile
să fie executate va trebuii ca acestea sp fie plasate într -un bloc finally.
Blocul finally este util fie pentru a evita scrierea unor instrucțiuni de ma i multe ori, fie
pentru a elibera resursele după părăsirea excepției.
Uneori, aruncarea unei excepții și golirea stivei până la blocul de tratare a excepției poate
să nu fie o idee bună. De exemplu, dacă excepția apare atunci când un fișier este deschis ( și
închiderea lui se poate face doar în metoda curentă), atunci ar fi util ca să se închidă fișierul
înainte ca să fie preluat controlul de către metoda apleată. Astfel supus, ar trebui să existe o
garanție că un anumit cod se va executa, indiferent daca t otul merge normal sau apare o excepție.
Acest lucru se face prin intermediul blocului finally , care se va executa în orice situație.
Existența acestui bloc elimină necesitatea existenței blocurilor catch (cu toate că și acestea pot să
apară).
1.3. Principi ile programării orientate pe obiecte
1.3.1 . Principiile programării orientate pe obiecte
Programarea orientată pe obiecte este unul din cei mai importanți pași făcuți în evoluția
limbajelor de programare spre o abstractizare cât mai puternică în implementarea programelor.
Crearea programele ca o colecție de obiecte, unități individuale de cod care interacționează unele
cu altele, în loc de simple liste de instrucțiuni sau de apleuri de proceduri reprezintă câteva dintre
ideile care stau la baza programării orientată pe obiecte .
Pentru a putea fi înțelese mai usor, cât și depanarea și extinderea lor față de programele
procedurale să fie mai usoară programele realizate cu ajutorul programării orien tate pe obiecte,
de obicei au o mare asemănare cu reprezentările obiectelor reale. În cazul proiectelor software
complexe și de dimensiuni mari se va observa că această afirmație în cele mai multe cazuri este
adevărată.
Principiile POO sunt:
1. Abstractizar ea – putem defini abstractizarea ca fiind procesul de a lua obiecte
reale și a le transforma în concepte virtuale, identificarea caracteristicilor și
14
comportamentului obiectelor . În urma abstractizării, entităților din domeniul
problemei se definesc prin c lase.
2. Încapsularea – se definește ca fiind înglobarea și ascunderea de informații într-o
clasă (structură) , este caracterizată prin două aspecte:
a. Componentele și caracteristicile sunt grupate într -un tip de date abstract
b. Poate definii unui obiect nivelul de acces
3. Moștenirea – este capacitatea de a crea noi clase plecând de la clase (generale)
care sunt deja definite , aceste noi clase au aceleași proprietăți și funcționalități ca
și clasele părinte. – acestea pot împărtăși (și extinde) comportamentul lor făra a fi
nevoie de redefinirea aceluiași comportament , într -un mod mai simplu putem
spune că moștenirea ajută la reutilizarea codului .
4. Polimorfismul – după cum supune și numele polimorfismul este c apacitatea ca
mai multe obiecte dintr -o ierarhie de clase de a utiliza denumiri de metode cu
același nume dar, cu un comportament și funcționalități diferit e.
1.3.2. Moștenirea
După cum bine știm operațiune a de moștenire mai poartă numele de derivare .
Moștenirea este operațiunea de extindere sau specializare a comportamentului unei clase
existente prin definirea unei clase noi ce moștenește datele și metodele clasei de bază, cu această
ocazie putând fi redefiniți unii membri existenți sau adăugați uni i membri noi.
Pentru a putea întelege mai bine denumirile și termenii specifici derivării/moștenirii avem
următoarele noțiuni:
– Clasa de bază/superclasă – este clasa din care se moștenește.
– Subclasă/clasă derivată/ clasă descndentă – este clasa care moștenește
una sau mai multe clase de bază.
– Ierarhie de clase – o clasă de bază împreună cu toate clasele descendente
(direct sau indirect) formează o ierarhie de clase.
– Clasa Object – este superclasa tuturor claselor . În C# toate clasele
moștenesc de la c alasa de bază Object .
15
Principiile moștenirii în C#:
– O subclasă poate să moștenească doar de la o singură clasă de bază.
– O clasă de bază poate fi derivată în mai multe subclase distincte.
– O subclasă poate fi clasa de bază pentru o altă clasă descendentă .
Atunci când vorbim de moștenire trebuie amintiți modificatorii abstract și sealed aplicați
unei clase, aceștia având rolul de a obliga procesul de derivare și respectiv de a se opune
procesului de derivare.
Cuvântul cheie abstract permite crearea de clase sau clase membrii, care sunt incomplete
ele trebuind să fie implementate în clasele derivate. O clasă abstractă nu poate fi instanțiată
scopul acesteia fiind acela de a oferi o definișie comună a unei clase de bază care poate dist ribuii
mai multe clase derivate.
O metodă abstractă este o metodă pentru care nu este definită o implementare, aceasta
urmând a fi realizată în clasele derivate din clasa curentă care trebuie să fie și ea abtractă.
Cuvântul cheie sealed înpiedică moștenirea unei clase sau a anumitor membri ai clase
care au fost declarate virtual . O clasă sealed nu poate fi utilizată ca o clasă de bază, ea
prevenind derivarea, din acest motiv o clasă sealed nu poate fi o clasă abstractă.
O metodă sigilată este o metodă care nu mai poate fi redefinită în clasele derivate din
clasa curentă.
1.3.3 . Polimorfism
Polimorfismul este capacitatea unei entități de a lua mai multe forme, să se afle în diferite
stări, și să aiba comportamente diferite. Polimorfisumu l obectual , are rolul de a se manifest a în
lucrul cu obiecte care aparțin unei ierarhii de clase, unde, prin redefinirea unor date sau metode,
se obține membri diferiți având însă același nume , el trebuind să fie abstract .
Pentru a fi permis acest mod de funcționare , metodele se declară ca metode virtuale (cu
modificatorul virtual ). În C# modificatorul virtual al funcției din superclasă , îi corespunde un
specificator override al funcției din clasa derivată ce redef inește funcția din superclasă .
16
În limbajul C# sunt admise trei tipuri de polimorfism :
Polimorfismul parametric – atunci când o metodă este creată, de regulă se cunoaște
numărul de parametrii care vor fi trimiși. Prin polimorfismul parametric se permite ca
o implementare de funcție să poată prelucra orice număr de parametri. Sunt cazuri în
care numărul de parametri nu este trimis, fiind nevoie de un număr arbitrar de
parametri. Acest lucru se poate obține prin folosirea unui tip special de parametru de
tipul params.
Polimorfismul ad -hoc se m ai numește și spuraîncărcarea metodelor , una dintre cele
mai interesante facilități oferite de limbajul C#. Cu ajutoru acestuia mecanism se pot
scrie mai multe metode, toate având acelaș i nume, dar tipuri și numere diferite de
parametri de aple. La compila re, se va apela funcția , pe baza corespondenței între
tipurile parametrilor de aple și tipurile parametrilor formali.
Polimorfismul de moștenire este forma cea mai evoluată de ploimorfism. Dacă în
precedentele forme de polimorfism nu se punea problema de moștenire, în acest caz
se pune problema apleării metodelor care au aceeași listă de parametri, dar care sunt
în clase diferite, astfel fiind necesară existența unei ierarhi de clase. Astfel spus o
superclasă trebuie să definească un tip care să fie compat ibil cu orice tip derviat, ca în
exemplu de mai jos:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HelloWorld
{
class Program
{
class Baza
{
public void Afisare() { Console.Write("Afiseaza din clasa de baza \n"); }
}
class Derivata : Baza
{
public void Afisare() { Console.Write("Afiseaza din clasa derivata" ); }
}
static void Main(string[] args)
{
Baza b = new Derivata();
b.Afisare();
Console.ReadKey();
}
}
}
17
1.4. ADO.NET
1.4.1 . Arhitectura ADO.NET
ADO.NET (ActiveX Data Objects) este un set de clase care expun serviciile de acces de
date pentru programatorii .NET Framework ce permite conectarea la surse de date diverse,
extragerea, manipularea și actualizarea datelor. ADO.NET oferă un set bogat de componente
pentru crearea și dist ribuirea aplicațiilor de partajare a datelor.
Este o parte integrata a .NET Framework, care oferă acces la date relaționale precum
XML și aplicații cu date. Suportă o varietate de nevoi de dezvoltare, inclusiv creearea de baze de
date, în cele mai multe ca zuri sursa de date este o bază de date, dar ar putea de asemenea să fie
un fișier text, o foaie Excel, un fișier Access sa u un fișier XML.
Pentru a putea întelege mai bine modul de funcșionare ADO.NET, ne putem reaminti din
aplicațiile mai vechi modul de s tabilire a unei conexiuni cu o baza de date, această conexiune
rămânând deschisă pâna la închiderea aplicației .
Întrucât majoritatea bazelor de date permit un numă r foarte mic de conexiuni concurente,
și menținerea unei conxiuni deschise alocă resurse din sistem, serverul de baze de date va avea
un timp de raspuns mult mai lent atunci când un client încearcă sa execute o comandă.
Prezentând modul de funcționalitate al aplicațiilor mai tradiționale și revenind la noile
tehnologi ADO.NET permite atât lucrul în stil conectat cât și lucrul în stil deconectat, aplicațiile
conectându -se la server -ul de baze de date numai pentru extragerea și actualizarea datelor. Acest
lucru reduce în mod considerabil timpul de răspuns al serverului de baze de date cât și reducer ea
numărului de conexiuni deschis e simulta n.
ADO.NET pune la dispoziție un set impresionant de instrumentele atât pentru utilizare și
reprezentare datelor XML, cât și pentru transferul datelor între aplicații și surse de date,
furnizând o reprezentare comu nă a datelor, ceea ce permite accesarea datelor din diferite surse de
diferite tipuri și prelucrarea lor ca entități, fără să fie necesar să convertim explicit datele în
format XML sau invers.
Aceste caracteristici sunt determinate în stabilirea beneficiil or furnizate de ADO.NET:
Interporabilitate. Aplicațiile ADO.NET pot profita de flexibilitatea și
interacționarea usoară cu orice componentă care suportă XML. Deoarece XML este
formatul pentru transmiterea seturilor de date în întreaga rețea, orice compone ntă care
poate citi formatul XML poate procesa datele.
Durabilitate. În viata unui sistem implementat, modificările modeste sunt permise,
pe când modificările substanțiale, arhitecturale sunt rareori încercate deoarece sunt
foarte dificil de realizat, ast fel ADO.NET permite dezvoltarea arhitecturii unei
aplicații datorită modului de transfer a datelor între nivelele arhitecturale.
18
Programabilitate. Componentele de date ADO.NET din Visual Studio înglobează
funcșionalitatea de acces la date în diferite moduri care ajută dezvoltatorul să
programeze mai rapid și cu mai puține greșeli, astfel ADO.NET simplifică
programarea pentru diferite task -uri cum ar fi comenzile SQL, ceea ce duce la o
creștere a produc tivității.
Performanță. Nu mai este necesar ă conversia explicită a datelor la transferul între
aplicații, fapt care duce la creșterea performanțelor acestora.
Accesibilitate. ADO.NET permite accesul si multan la același set de date prin
utilizarea arhitecturii deconectate . Utilizarea optimă a resurselor se datorează astfel
reduceri numărului de conexiuni simultan.
Componentele principale ale ADO.NET sunt DataSet și Data Provider. Ele au fost
proiectate pentru accesarea și manipularea datelor.
Figura 1.5 . Arhitectura ADO.NET
19
1.4.2 . Furnizori de date în ADO.NET
Modelul de date ADO.NET oferă o interfață comună în .NET Framework pentru
conectarea și interacționarea cu o bază de date.
.NET Framework include furnizori de ADO.NET pentru acces direct la Microsoft SQL
Server dar și pentru accesul indirect la alte baze de date cu drivere ODBC și OLE DB. Pentru
accesul direct la alte baze de date, există o gamă largă de furnizori de baze de date disponibili
după cum se arată în tabelul de mai jos. Toți furnizori prezenți în Tabelul (1.1) includ suport
Entity Framework.
Din cauza existenței mai multor tipuri de surse de date este necesar ca pentru fiecare tip
de protocol de comunicare să se folosească o bibli otecă specializată de clase. Toate aceste clase
implementează niște interfețe bine stabilite, ca atare trecereade la un SGBD la altul se face cu
eforturi minore (dacă codul este scris ținând cont de prinicipiile programării orientate pe
obiecte).
Nume furnizor Descriere
MySQL MySql este un driver ADO.NET complet
gestionat, scris 100% în C#, care permite
dezvoltatorilor să creeze cu ușurință
aplicații .NET
Oracle Providerul de date Oracle pentru .NET
optimizează accesul la baza de date Oracle.
Devart Oferă furnizorilor de ADO.NET oferă acces la
providerii de date ca Oracle, MySQL, SQL
Lite, PostgreSQL, și Microsoft SQL Server.
ODBC Data Provider Surse de date cu interfată ODBC (baze de date
vechi)
OleDb Data Provider Surse de date care expun o interfată OleDb, de
exemplu Access și Excel sau SQL Server
versiune mai veche de 7.0
Borland Data Provider Acces generic la SGBD -uri precum Interbase,
SQl Server, IBM DB2, Oracle
IBM IBM furnizează furnizori de date ADO.NET
pentru acces la DB2, Informix, și U2.
Tabelul 1.1 . Furnizori de date.
20
Furnizorul de date permite unei aplicații să se conecteze la sursa de date, execută
comenzi și salvează rezultate. Fiecare furnizor de date cuprinde componentele Connection ,
Command , DataReade și DataAdapter .
1.4.3 . Connection
Pentru a putea realiza o operație sau un set de operații cu o sursă de date externă, trebuie
realizată o conexiune cu acea sursă de date.
Pentru realizarea unei conexiuni cu o sursă de date sunt necesare introducerea unor date
referitoare la sursa de date la care dormim să ne conectăm și anume: locația, numele și parola
contului de acces, etc. toate acestea acestea aparținând claselor din categoria Connection
(SqlConnection, OleDbConnection etc.). Aceste clase se găsesc în subsp ații ( SqlClient, OleDb
etc.) ale spațiului System.Data . În plus, ele implementează interfata IdbConnection .
Pentru deschiderea unei conexiuni prin program se poate instanția un obiect de tip
conexiune, precizându -i ca parametru un șir de caractere conținân d date despre conexiune ca in
exemplul următor:
SqlConnection con = new SqlConnection ();
con.ConnectionString = @"Data Source=EDY; Initial Catalog=REINVESTIRE -PROFIT; Integrated
Security=SSPI" ;
con.Open();
ConnectionString – definește un ș ir cu ajutorul câruia se poate identifica tipul și
sursa de date la care se face conectarea și eventual contul și parola de acces. Sirul
definit coține un set de parametri necesari conectării ei fiind sub forma
parametru=valoare , separarea lor se face prin pu nct și virgu lă ”;”. Lisata
parametrilor:
– Provider – Parametrul provider este destinat pentru a furniz a furnizoru de
date al bazei de date la care se va conecta . Acest furnizor trebuie precizat
doar dacă se folosește OleDb .NET Data Provider, și nu se specifică
pentru conectare la SQL Server.
– Data Source – Acest parametru are rolul de a identifica serverul la care
utilizatorul dorește să se conecteze , care poate fi local, un domeniu sau o
adresă IP.
– Initial Catalog – În acest parametru trebuie specificat numele bazei de
date. Baza de date trebuie să se găsească pe serverul dat în Data Source.
– Integrated Security – Logarea se face cu user -ul configurat pentru
Windows.
– User ID – Numele unui user care are acces de logare pe server.
21
– Password – Parola corespunzătoare ID -ului specificat.
Database – returnează numele bazei de date care s -a făcut conectarea. Este necesară
pentru a arăta unui utilizator care este baza de date pe care se face operarea.
Provider – returnează furnizorul de date.
ServerVersi on – returnează versiunea de server la care s -a făcut conectarea.
State – returnează starea curentă conexiunii. Valorile posibile: Broken, Closed,
Connecting, Fetching, Open.
1.4.3.(1) Metode
1. Open() – deschide conexiune a la baza de date.
2. Close(), Dispose() – închid conexiunea și eliberaează toate resursele alocate
pentru ea.
3. BeginTransaction() – pentru a se putea executa o tranzacț ie pe baza de date, la
sfârșit este necesară apelarea uneia din metodele Commit() sau Rollback() .
4. ChangeDatabase() – această metodă perimite modificarea bazei de date asupra
căreia se vor face conexiunile. Pentru ca metoda să funcționeze trebuie menționat
faptul ca n oua bază de date trebuie să existe pe același server ca precedenta.
5. CreateCommand() – creează un obiect d e tip Command valid (care
implementează interfata IdbCommand ) asociat cu conexiunea curentă.
1.4.3.(2) Evenimente
1. StateChange – apare atunci când se schimbă starea conexiunii. Handlerul
corespunzător ( de tipul delegat stateChangeEventHandler ) spune într e ce stări s –
a făcut tranziția.
2. InfoMessage : apare când furnizorul trimite un avertisment sau un mesaj către
client.
22
1.4.4. Command
Clasele care se regăsesc în categoria Command ( SqlCommand, OleDbCommand etc. )
conțin date referitoare la o comandă SQL (SELECT, INSERT, DELETE, UPDATE) și metode
pentru executarea unei comenzi sau a unor proceduri stocate. Aceste clase implementează
interfata IdbCommand . Ca urmare a interogării unei baze de date se obțin obiecte din categoriile
DataR eader sau DataSet . O co mandă se poate executa numai după ce s -a stabilit o conexiune cu
baza de date corespunzătoare.
Obiectele de tip SqlCommand pot fi utilizate într -un scenariu ce presupune deconectarea
de la sursa de date dar și în operații elementare care presupun obșinere a unor rezultate imediate.
Proprietăți :
1. CommandText – conține numele procedurii stocate sau comanda SQL care se va
execut a pe sursa de date.
2. CommandTimeout – această metodă impune un numărul de secunde dat de
dezvoltator care trebuie să fie așteptat pentru executarea comenzii. Dacaă se
depășeste acest timp, atunci se generază o excepție.
3. CommandType – reprezintă tipul de comandă care se execută pe sursa de date.
Valorile pot fi: StoredProcedure (apel de procedură stocată ), Text (comandă SQL
obișnuită), tableDirect (numai pentru OleDb).
4. Connection – conține obiectul de tip conexiune folosit pentru legarea la sursa de
date.
5. Parameters – returnează o colecție de parametri care s -au transmis comenzii.
6. Transaction – permite accesul la obiectul de tip tranzacție care se cere a fi
executat pe sursa de date.
23
1.4.5. DataReader
DataReader permite explorarea datelor în modul conectat (cu ajutorul unor obiecte din
categoria DataReader ), sau pot fi preluate de la sursă (dintr -un obiect din categoria
DataAdapter ) și înglobate în aplicația curentă (sub forma unui obiect din categoria DataSet ).
Clasele DataReader permit parcurgerea într -un singur sens a sursei de date, făra
posibilitatea de modificare a datelor la sursă. Dacă se dorește modificarea datelor la sursă, se va
utiliza ansamblul DataAdapter + DataSet . Datorită faptului că citește doar înainte ( forward –
only) permite acestui tip de date să fie foarte rapid în citire. Overhead -ul asociat este foarte mic
(overhead generat cu inspectarea rezultatului și a scrierii în baza de date).
Dacă într -o aplicație este nevoie doar de informații care vor fi citite o singură dată , sau
rezultatul unei interogări este prea mare ca să fie reținut în memoria (caching) DataReader este
soluția cea mai bună.
Un obiect DataReader nu are constructor, ci se obține cu ajutorul unui obiect de tip
Command și prin apelul metodei ExecuteRea der(). Evident, pe toată durata lucului cu un obiect
de tip DataReader , conexiunea trebuie să fie activă. Toate clasele DataReader (SqldataReader,
OleDbDataReader etc.) implementează interfața IDataReader .
1.4.5.(1). Proprietăți
IsClosed – dacă obiectul este deschis va returna valoarea true, respectiv false daca
obiectul este închis.
HasRows – verifică dacă există cel puțin o înregistrare în reader .
Item – reprezintă indexatorul de câmpuri .
FieldCount – verifică câte câmpuri sunt în înregistrarea curentă și returnează numărul
acestora.
1.4.5.(2). Metode
Close() – această metodă are rolul de a elibera resursele și de a închide o biectul la
rândul ei trebuind să preceadă închiderea conexiunii.
24
GetBoolean(), GetByte(), GetChar(), GetDa teTime(), GetDecimal(), GetDouble(),
GetFloat(), GetInt16(), GetInt32(), GetInt64(), GetValue(), GetString() – toate aceste
metode au rolul de a returnea valoarea unui câmp specificat, din înregistrarea curentă.
GetBytes(), GetChars() – caceastă metodă es te utilizată pentru a citi octeți sau
caractere dintr -un câmp de date binar.
GetDataTypeName(), GetName() – aceste metode au scopul de a returna tipul sau
numele câmpului specificat ca parametru.
IsDBNull() – verifică dacă în câmpul sepcificat prin index este o valoare nulă în caz
afirmativa metoda va returna valoarea true.
NextResult() – determină trecerea la următorul rezultat stocat în obiect.
Read() – are rolul de a trece la următoarea înregistrare iar î n cazul în care aceasta nu
există se va returna valoarea false .
DataReader este folosit cel mai adesea pentru a obține datele într -un stream secvențial.
Pentru a putea citi informații le din stream -ul respectiv trebuie apelată metoda Read , aceasta
citești nd din tabelul rezultat doar un singur rând . Pentru a putea citi toate informațiile existente
intr-un DataReader se folosește metoda clasică de iterare intr -o buclă while.
1.4.6. DataAdapter
La fel ca și Connection, Command, DataReader, obiectele de tip DataAdapter fac parte
din furnizorul de date .NET specific fiecărui tip de sursă de date. Scopul clasei este să permită
umplerea unui obiect DataSet cu date și reflectarea schimbărilor efectuate asupra acestuia înapoi
în baza de date ( DataSet permite lucrul deconectat de la baza de date).
În cazul în care sunt folosite simultan obiectele DataAdapter și DataSet este permisă
realizarea unui set operații ca: selectare a, ștergere a, modificare a și adăugare a în baza de date.
Clasele DataAdapter gene rează obiecte care funcționează ca o interfață între sursa de date și
obiectele DataSet interne aplicației, permițând prelucrări pe baza de date. Ele gestionează
automat conexiunea cu baza de date astfel încât conexiunea să se facă numai atunci când este
necesar.
Un obiect DataSet este de fapt un set de tabele relaționale. Folosește serviciile unui
obiect DataAdapter pentru a -și procura datele și trimite modificările înapoi către baza de date.
Datele sunt stocate de un DataSet în format XML, același folosit și pentru transferul datelor.
25
Metode
Constructori au rolul de a specifica o comandă de tip SELECT și conexiunea la sursa
de date. Pentru un obiect de tip SqlD ataAdapter se poate crea o instanță în următorele
moduri:
SqlDataAdapter da = new SqlDataAdapter ();
sau
SqlCommand cmd = new SqlCommand ("SELECT * FROM REINVESTIRE -PROFIT");
SqlDataAdapter da = new SqlDataAdapter ();
Fill() – această metodă permițând popularea unei tabele dintr -un obiect de tip DataSet
cu date. Permite specificarea obiectului DataSet , numărul de înregistrări c u care să se
înceapă popularea și numărul de înregistrări care au fost aduse din bază. În clipa în
care se apelează Fill() se procedează astfel:
a) În cazul în care conexiunea nu a fos t explicit deschisă aceasta se va
deschide.
b) Se populează un obiect de tip DataTble din DataSet .
c) Se închide conexiunea, dacă aceasta nu a fost explicit deschisă).
Un DataAdapter își poate deschide și închide singur conexiunea, dar dacă aceasta a
fost deschisă înaintea metodei Fill() atunci tot programul trebuie să se închidă.
Update() – această metodă permite reflectarea modificărilor efectuate între -un
DataSet . Pentru a funcțio na are nevoie de obiecte de tip comandă adecvate:
proprietățile InsertCommand, DeleteCommand și UpdateCommand trebuie să indice
către comenzi valide. Returnează de fiecare dată numărul de înregistrări afectate.
26
1.5. Tehnologii SMTP (Simple Mail Transfer Protocol)
1.5.1 . Ce este SMTP?
Simple Mail Transfer Protocol (prescurtat, SMTP; în traducere aproximatvă Protocolul
simplu de transfer al corespondenței) este parte a stratului de aplicare a protocolului TCP/IP.
Folosind un proces numit ”stocare și redirecționare”, SMTP mută adresa dvs. de email pe și în
rețele. Aceasta lucrează în strânsă colaborare cu Agentul de transfer de Mail (MTA) pentru a
trimite comunicarea la emil -ul și calculatorul corect.
SMTP precizează și direcționează cum email -ul de pe MTA -ul calculatorului
dumneavoastră se muta pe MTA -ul altui calculator, sau chiar pe mai multe calculatoare.
Folosind facilitatea mentionată anterior ”stocare și redirecționare”, mesajul se poate deplasa în
mai muți pați de la calculator la destinaț ie. La fiecare pas Simple Mail Transfer Protocol își va
face treaba, toti acești pași realizându -se în spatele SMTP -ului.
SMTP este un protocol simplu, folosit pentru transmiterea mesajelor în format electronic
pe internet. SMTP folosește portul de aplic ație 25 TCP și determină adresa unui server SMTP pe
baza înregistrării MX ( Mail eXchange, ”schimb de corespondență”) din configurația serverului
DNS.
Protocolul SMTP specifică modul în care mesajele de poștă electronică sunt transferate
între procese SMT P aflate pe sisteme diferite. Procesul SMTP care are de transmis un mesaj este
numit client SMTP iar procesul SMTP care primește mesajul este Serverul SMTP. Protocolul nu
se referă la modul în care mesajul ce trebuie transmis este trecut de la utilizator c ătre clientul
SMTP, sau cum mesajul recepționat de serverul SMTP este livrat utilizatorului destinatar și nici
cum este memorat mesajul sau de câte ori clientul SMTP încearcă să transmită mesajul.
1.5.2. Clasa MailAddress
Clasa MailAddress este utilizat ă de către clasele SmtpClient și MailMessage să stocheze
informații adresă pentru mesajele de e -mail. O adesaă de e -mail este compusa dintr -un nume de
utilizator, un nume gazdă și optțional un DisplayName . DisplayName poate conține caractere
non-ASCII, dac ă ele sunt codificate.
27
Clasa MailAddress acceptă următoarele formate de adese e -mail:
Un format adesă simplu user@host . Dacă un DisplayName este setat deja, acesta va
fi formatul mail generat.
Un citat standard pentru afisare formatului de nume ”display name” <user@host> .
Dacă un DisplayName este setat deja, acesta va fi formatul mail generat.
Parantezele unghiulare sunt adaugate în jurul numelui de utilizator si al numelui
gazdă ”display name” user@hostâ dacă acestea nu sunt incluse.
Citatele sunt adăugate în jurul ” DisplayName ” pentru display <name user@host>
dacă acestea nu sunt incluse.
Caracterele Unicode sunt acceptate în DisplayName .
Un utilizator de nume cu citate. De exemplu ”user name”@host .
Puncte consecutive în numele de utilizator. De ecemplu user…name..@host .
Paranteze. De exemplu <user@[my domain]> .
1.5.3 . Clasa SmtpClient
Clasa SmtpClient este folosită pentru a trimite e -mail la un server SMT P pentru livrare,
protocolul SMTP fiind definit în RFC 2821.
Clasele prezentate în tabelul de mai jos sunt folosite pentru a construi mesaje e -mail care
pot fi trimise folosind SmtpClient.
Clasă Descriere
Attachment Reprezintă fișierele atașate. Această clasă vă
permite să atașați fișiere, fluxuri, sau text la un
mesaj de e -mail.
MailAddress Reprezintă adresa de e -mail a expeditorului și a
destinatarilor.
MailMessage Reprezintă un mesaj de e -mail.
Tabelul 1.3 . Clasele folosite pentru constuirea unui mesaj e -mail folosind SmtpClient..
28
Pentru a construi și a trimite un mesaj de e -mail cu ajutorul SmtpClient, trebuie să
specificați următoarele informații:
Serverul gazda SMTP pe care îl utilizați pentru a trimite e -mail.
Acreditările pentru autentificar e, dacă este necesar prin serverul SMTP.
Adresa de e -mail a expeditorului.
Adesa de e -mail sau adresele destinatarilor.
Conținutul mesajului.
Pentru a include o atașare cu un mesaj de e -mail, mai întâi creați atașarea utilizând clasa
Attachment, și apoi adăugațil la mesaj folosind MailMessage .
Conexiunea stabilită de instanța curentă a clasei SmtpClient la serverul SMTP poate fi
reutilizată daca se dorește trimiterea mai multor mesaje la același server SMTP. Acest lucru este
deosebit de util atunci c ând autentificarea sau criptarea sunt folosite pentru a stabili o conexiune
la serverul SMTP. Procesul de autentificare și de stabilire a unei sesiuni TLS poate fi o
operațiune costisitoare. O cerință de a restabili o conexiune pentru fiecare mesaj atunci când se
trimite un e -mail cu o cantitate mare la serverul SMTP ar putea avea un impact semnificativ
asupra performanței.
Clasa SmtpClient nu conține metoda Finalize , așa că este necesară apelarea metodei
Dispose pentru a elibera în mod explicit resursele. Metoda Dispose iterează prin toate
conexiunile stabilite la serverul SMTP specificat în proprietatea gazdă și trimite un mesaj QUIT
urmat de închiderea conexiuni TCP. Metoda Dispose eliberează, de asemenea, resur sele
negestionate utilizate de Socket și obțional dispune de resursele gestionate.
1.5.4 . Clasa MailMessage
Clasa MailMessage permite, de asemenea, permite accesarea colectiei de antete pentru un
mesaj folosit ca antet. În timp ce această colecției este r ead-only (o nouă colecție nu poate fi
setată), antetele personalizate pot fi adăugate sau eliminate din această colecție. Orice antet
personalizat și adaugat va fi inclus atunci când instanța MailMessage este trimisă. Înainte de a
expedia un mesaj, doar an teturile adâugate special pentru această colecție vor fi incluse in
colecție.
Dacă unele antete mail sunt malformate, acestea ar putea provoca mesajul e -mail să
devină corupt. Deci orice antet mail în colecția de antete care poate fi setat cu ajutorul un ei
29
proprietăți din clasa MailMessage ar trebui stabilit numai cu ajutorul proprietății clasei
MailMessage sau cu un paramteru atunci când MailMessage inizializează un obiect de tip
MailMessage.
1.6. Algoritmi
1.6.1 . Algoritmul Greedy
Algoritmul Greedy est e un algoritm care urmărește problema rezolvării euristice de a
face alegerea optimă locală la fiecare etapă cu speranța de a găsi un optim global. În multe
probleme, strategia greedy in general nu produece cea mai optimă soluție, dar cu toate acestea o
relolvare greedy euristică poate rezulta soluții optime pe plan local care aproximează o soluție
optimă globală într -un timp rezonabil.
Traducerea c uvântul ui ”greedy” care provine din limba engleză înseamnă ”lacom”.
Algoritmii de tip greedy vor sa construiască într -un mod cât mai rapid soluția unei probleme. Ei
se caracterizează prin luarea unor decizii pe baza unui criteriu optim simplu și usor de verificat,
care duc la găsirea unei soluții a problemei. Nu întotdeauna asemenea decizii verificabile ușor
duc la o soluție optimă, de aceea trebuie să reușim identificarea acelor tipuri de probleme pentru
care se pot obține soluții optime.
Algoritmii greedy sunt în general simpli, folisiți la probleme de optimizare și se numara
printre cei mai direcți alg oritmi posibili. Principiul de funcționalitate al algoritmului greedy este
simplu: pentru a putea rezolva o problemă de optimizare, de calculare a unui cost minim sau
maxim, se va alege la fiecare pas deciziacea mai favorabilă, fără a evalua global eficie nța
soluției. Conform anumitor criterii algoritmul greedy va selecta doar anumite soluții pe care el le
considera optime. Conform criteriului optimal impus scopul unui algoritm greedy este acela de a
găsi cea mai optimă soluție sau o soluție cât mai apropi ată.
În general algoritmii greedy au cinci componente:
– Un set candidat, din care este creată o soluție.
– O funcție de selecție, care alege cel mai bun candidat pentru a fi adăugat la
soluție.
– O funcție de fezabilitate, care este folosită pentru a determina dacă un
candidat poate fi utilizat pentru a contribui la o soluție.
– O funcție obiectiv, care atribuie o valoare unei soluții, sau o soluție
parțială.
– O funcție soluție, care va indica când am descoperit o soluție completă.
30
Este de înțeles faptul că soluția obținută este optimă doar dacă o soluție optimă locală
conduce la o soluție optimă globală.
Dupa cum am precizat și mai sus un algoritm greedy în general nu produce cea mai
optimă soluție spre exemplu atunci când deciziile de la un pas influențează lista de decizii de la
pasul următor, este posibilă obținerea unei valori neoptimale.
Descrierea formală a unui algoritm greedy este:
( )
//
//
( )
( )
* +
( * +) * +
În concluzie algoritmul greedy alege la fiecare pas cel mia bună decizie de la pasul
respectiv, fără a analiza situațiile viitoare, de unde și denumirea de lacom.
Odată ce a fost aleasă o soluție aceasta nu mai poate revoca sau schimba de unde putem
deduce faptul că o soluție parțială nu va mai avea posibilitatea sa fie reevaluată la un pas anterior
aceasta fiind abandonată .
31
Capitolul 2.
Fundamente – SQL Server
2.1. SQL Server
2.1.1 . Scurtă introducere
O bază de date este o aplicație separată, care stochează o colecție de date. Fiecare bază de
date are una sau mai multe API -uri distincte pentru crearea, accesarea, administrarea, căutarea și
replicarea datelor pe care le dețin. În zilele noastre se folosesc sisteme de management al bazelor
de da te relaționale (RDBMS) pentru a stoca și manageria un volum imens de date. Aceasta se
numește bază de date relațională, deoarece toate datele sunt stocate în diferite tabele și relațiile
sunt stabilite folosind chei primare sau a altor chei cunoscute sub n umele de chei externe. Un
sistem de management de baze de date (RDBMS) este un software care:
permite să punem în aplicare o bază de date cu tabele, coloane, și indici,
garantează integritatea referențială între rânduri de diferite tabele,
actualizează indicii automat,
interpretează o interogare SQL și combină informațiile din diferite tabele.
Terminologia RDBMS
Înainte de a trece la explicarea sistemului de baze de date SQL Server, voi revizui câteva
definiții legate de baze de date.
Bază de date : O bază de date este o colecție de tabele, cu date aferente.
Tabel : Un tabel este o matrice cu date. Un tabel într -o bază de date arată ca o foaie de
calcul simplu.
Coloană : O coloană (element de date) conține date doar de un singur tip, de exemplu,
coloana CodProdus.
32
Rând : Un rând (intrarea sau înregistrarea) este un grup de date întrudite.
Redutanță : Reprezintă s tocarea în mod nejustificat a unei aceleași informații de mai
multe ori în baza de date pentru a face sistemul mai rapid .
Cheie primară : Constrângerea cheie primară creează o cheie primară pentru tabel.
Numai o singură cheie poate fi creată pentru fiecare tabel. Această constrângere este
o coloană sau un set de coloane care identifică în mod unic fiecare rând al tebelului.
Nicio coloană care f ace parte din cheia primară nu poate contine valoare nulă.
Cheie externă : O cheie externă este PIN -ul de legătură între două tabele. Această
constrângere definește o coloană sau o combinație de coloane ca cheie externă și
stabilește o relație între o chei e primară și una unică în același tabel sau în tabele
diferite. O valoare care apare într -un tabel trebuie să se regăsească și în cel de -al
doilea tabel, pe coloana unde se formează cheia primară. Constrângerile de tip cheie
externă pot fi definite la nive l de coloană sau de tabel.
Cheie compusă : O cheie compusă (cheie compozit) este o cheie care constă din mai
multe coloane.
Index : Un index într -o bază de date seamănă cu un indice de la partea din spate a
unei cărți.
Integritate referențială : Integritatea referențială se asigură că o valoare cheie
externă arată întotdeauna un rând existent.
SQL Server Database
Microsoft SQL Server este un sistem de gestionare de baze de date relaționale (RDBMS),
produs de compania americană Microsoft. Micro soft SQL Server folosește o variantă SQL numit
Transact SQL (T -SQL), care este o implementare de SQL -92 cu unele extensii pentru
procedurile stocate și tranzacții.
SQL Server este un RDBMS rapid, ușor de utilizat, folosit atât pentru întreprinderile mici
cât și pentru inteprinderi mai mari. SQL Server a devenit popular, din mai multe motive bune.
Microsoft pune la dispoziție varianta SQL Server Express care a fost lansată sub o
licenta open -source.
33
SQL Server este un program foarte puternic. Se ocupă de u n subset mare de
funcționalități a pachetelor de baze de date mai scumpe și puternice.
SQL Server funcționează pe mai multe sisteme de operare și cu mai multe limbaje ,
inclusiv C+, Java C#, etc.
SQL Server acționează foarte rapid și funcționează bine și cu seturi mari de date.
2.1.2 . Modelarea datelor
Proiectarea corectă a structurii unei baze de date relaționale este o premisă fundamentală
în scrierea programelor de plicație și în funcționarea lor fără anomaliile care pot apărea în cazul
unei structuri defectuase. Proiectarea stucturii bazelor de date relaționale este un domeniu în
care cercetările au evoluat spre evoluare unor metodologii teoretice și a unor instrumente
software care asigură un grad ridicat de normalizare a schemelor de r elație, păstrarea integrității,
evitarea anomaliilor datorate unei proiectări nesistematice.
Cateva dintre anomaliile care le -am putea întalni pe parcursul funcționării unei aplicație
ar putea fi:
Reduntanța : reprezintă stocarea în mod nejustificat a unei aceleași informații de mai
multe ori în baza de date.
Anomalia de stergere : spre exemplu la ștergerea din relație a ultimului produs al
unui furnizor se pierd automat și datele despre acesta.
Anomalia de actualizare : în cazul actualizării unei inform ații redutante, se poate
întampla ca operația să modifice unele apariții ale acesteia iar altele să ramană cu
vechea valoare.
Anomalia de inserare : nu permite inserarea de date despre un furnizor decât dacă
există în stoc un produs furnizat de acesta.
Impactul conceptelor de abstractizare și generalizare precum și elaborarea unui model de
descriere informal a datelor, și anume modelul entitate -asociere (EA), au dus la găsirea unor căi
algoritmizabile de proiectare optimă a bazelor de date. Modelul entitat e-asociere este în acest
34
moment cel mai populare model de comunicare a structurii bazelor de date datorită intuitivității
și simplității elementelor sale.
Extensiile modelului EA au apărut și pentru alte necesități:
Modelarea cerințelor de secretizare a datelor,
Documentarea programelor de aplicație și ușurarea comunicării între proiectantul de
sistem și utilizatorul obișnuit,
Proiectarea bazelor de date complexe pe porțiuni și integrarea ulterioară a acestora
(așa numita integrare a vederilor).
Avantaj ul principal al modelului EA este acela al simplității sale și al caracterului său
intuitiv. Rezultatul proiectării constă într -o diagramă entitate -asociere care poate fi apoi
translatată în modelul de date folosit de sistemul de gestiune a bazelor de date ales pentru
dezvoltarea aplicației.
Analiza de sistem
În acestă etapă se realizează analiza segmentului din lumea reală care va fi gestionat de
aplicația respectivă. Rezultă o specificație neformalizată a cerințelor constând din două
componente:
1. Cerințe privind conținutul bazei de date : categoriile de date care vor fi stocate
și interdependențele dintre acestea.
2. Cerințe privind prelucrările efectuate de aplicație : prelucrările efectuate
asupra datelor, arborele de meniuri al aplicației, machetele formatelor de
introducere și prezentare a datelor și ale rapoartelor tipărite de aceasta.
În general această etapă nu poate fi asistată prin programe de tip CASE dar există reguli
care ajută proiectantul în realizarea sa. Activitățile desfășurate includ:
Analiza activității desfășurate la momentul respectiv de beneficiarul aplicației sau de
o mulțime reprezentativă de beneficiari în cazul aplicațiilor de uz general.
Analiza conținutului de date și a funcționalității aplicațiilor software – dacă există –
care vor fi înlocuite de noua aplicație incluzând meniuri, machete ecran și machete de
rapoarte.
35
Analiza formularelor tipizate și a altor documente utilizate de beneficiar pentru
realizarea activității respective.
Identificarea tuturor interdependențelor dintre datele care vor fi stocate în baza de
date și a restricțiilor privind valorile pe care le pot lua anumite categorii de date.
Identificarea – dacă este cazul – a prelucrărilor care se declanșează automat atât în
cazul modificării bazei de date cât și la momente prestabilite de timp (de exemplu
sfârșit de lună, de an, etc.).
Identificarea operațiilor care sunt necesare beneficiarului în activitatea curentă dar
care în acest moment nu sunt realizate prin intermediul aplicațiilor software folosite
precum și a operațiilor care pot fi incluse în mod natural în noua aplicație.
Identificarea bazelor de date existente care pot fi folosite de noua aplicație – direct sau
printr -un import inițial de date – evitându -se în acest fel reintroducerea manuală a
acestora.
Identificarea modalităților de transfer de date între noua aplicație și alte aplicații care
rulează deja la beneficiar și care vor fi folosite și în viitor de către acesta.
Identificarea necesitățiilor privind datele și prelucrările care pot fi în viitor necesare
beneficiarului, deci a posibilelor dezvoltări în timp ale aplicației.
Proiectarea conceptuală a bazei de date
În această etapă, pornind de la rezultatele analizei de sistem, se realizaeză modelarea
cerințelor privind datele folosi nd un model de nievl înalt. Cel mai popular model folosit pentru
aceasta este modelul entitate -asociere. Actualmente există pe piată numeroase instrumente CASE
care folosesc diverse variante ale modelului. Motivele pentru care a fost ales sunt următoarele:
Nu este legat direct la nici unul dintre modelele folosite de sistemele de gestiune a
bazelor de date (relațional sau orientat obiect) dar există algoritmi bine puși la punct
de transformare din modelul EA în celelalte modele de date.
Este intuitiv, rezultatul modelării fiind o diagramă care definește atat datele stocate în
baza de date cât și interdependențele dintre acestea.
36
Poate fi usor de înteles. Această caracteristică este foarte importantă în mementul în
care se face punerea de acord cu benef iciarul asupra structurii bazei de date a
aplicației, evitându -se în acest fel o proiectare neconformă cu realitatea sau cu
cerințele exprimate de acesta.
Proiectarea se poate face pe porțiuni, diagramele parțiale rezultate putând fi apoi
integrate pe baz a unor algoritmi și metode bine puse la punct.
Transformarea în model relațional
În aceată etapă entitățile și asocierile care formează EA se transformă pe baza unor reguli clare în
structura relațională a bazei de date . Rezultă schema preliminară a acesteia formată din tabele, coloanele
acestora și constrângerile de integritate care pot fi deduse automat din diagramă incluzând unele
interdependențe între date numite dependențe funcționale .
2.1.3 . Normalizarea bazelor de date
Există câteva seturi de condiții care ne arată că o schemă de relație este corect proiectată
în sensul că ea nu permite apariția anomaliilor prezentate la începutul capitolului. Dacă schema
îndeplinește cerințele unui anumit set de condiții se spune că este în forma normală asociată
acestui set.
În continuare sunt prezentate următoarele tipuri de forme normale.
Prima formă normală (1NF – First Normal Form) . Prima formă normală este
forma normală utilizată în normalizarea bazelor de date. Aceasă forma normală
exclude posibilitatea existenței grupurilor repetitive cerând ca fiecare câmp într -o
bază de date să cupri ndă numai o valoare atomică. De asemenea, prima forma
normală cere ca fiecare înregistrare să fie definită astfel încât să fie identificată în
mod unic prin intermediul unei chei primare.
A doua formă normală (2NF – Second Normal Form) . A doua formă norma lă cere
ca toate elementele unei tabele să fie dependente funcțional de totalitatea cheii
primare. Dacă unul sau mai multe elemente sunt dependente funcțional numai de o
parte a cheii primare, atunci ele trebuie sa fie separate în tabele diferite. Dacă tab ela
are o cheie primară dormată din numai un atribut, atunci ea este automat în 2NF.
A treia formă normală (3NF – Third Normal Form) . A treia formă normală cere
ca toate atributele non -chei ale unei relații să depindă numai de chei candidate ale
acelei re lații. Bill Kent: ”the relation is based on the key, the whole key and nothing
37
but the key”, la care unii adaugă: ”so help me Codd” (”relația depinde de cheie, de
intreaga cheie si de nimic altceva decât de cheie”, la care unii adaugă ”asa să ne ajute
Codd ”). Toate atributele non -chei sunt (trebuie să fie) mutual independente.
Forma normală Boyce -Codd (BCNF – Boyce Codd Normal Form) . Boyce -Codd e
o versiune puțin mai restrictivă de forma normală 3. În cazul unei forme normale 3,
toate atributele depind de o cheie, o cheie în întregime și numai de o cheie.
A patra forma normala (4NF – Fourth Normal Form) . Cu toate că BCNF elimină
toate anomaliile datorate dependențelor funcționale, mai există un tip de dependență ,
numită dependență multivalorică, ce poate cauza probleme de redutanță a datelor. A
patra formă normală este o formă mai strictă dect BCNF pentru că împiedică relațiile
să conțină dependențe multivalorice, prevenind astfel redutanța datelor. Normalizarea
de la BCNF la 4NF presupune eliminarea depen dențelor multivalorice prin plasarea
atributului (atributelor) într -o nouă relație împreună cu o copie a determinantului.
2.1.4 . Securitatea aplicațiilor cu baze de date
Securitatea este asigurată pe mai multe niveluri:
Controlul accesului la nivelul sistemului de operare.
Controlul accesului la o rețea locală sau internet.
Controlul accesului la nivel de aplicație software.
Controlul accesului la nivel SGBD (Sistem de Gestiune a Bazei de Date).
38
Capitolul 3 .
Aplicație: Dezvoltarea aplicativă
3.1. Descrierea aplicației
3.1.1 . Motivul aplicației
Această aplicație reprezintă proiectul de licență în cadrul Universității din Pitești, și are
ca scop realizarea unei aplicații desktop vizuală , securizată (cu nume de utilizator și parolă), și cu
fluxul de gestiune a datelor. Aplicația numită ”Reinvestirea profitului unei firme în baza
materială” are ca obiective:
1. securizarea aplicației prin nume de utilizator și parolă,
2. reducerea timpului de introducere a datelor prin implementarea modului de
gestiune al datelor din Excel și oferirea unei soluții astfel încât profitul rămas să
fie minim – exportul datelor în Excel și
3. trimiterea prin Email.
Lucrarea de fată descrie cele mai des întalnite tehnici de definire și utilizare a bazelor de
date precum și a documentelor Excel, însoțite de o exemplificare prin aplicatia Reinvestirea
profitului unei firme in baza materiala realizată in C#. Aplicația de fată este un exemplu de ceea
ce se poate realiza folisind tehnologiile respective.
Lucrarea este structu rată în trei capitole, fiecare avand mai multe subcapitole, urmate de
o serie de concluzii și listă cuprinzătoare de referințe bibliografice.
Tema lucrării intitulată „Reinvestirea profitului unei firme in baza materiala” extinde o
suită de tehnologii Mic rosoft care au la bază Framework -ul .NET ce reprezintă un cadru de
dezvoltare software unitară care permite realizarea, distribuirea și rularea aplicațiilor desktop
Windows și aplicațiilor WEB.
Motivul alegerii acestei teme îl constituie posibilitatea care mi s-a dat în a lucra la un
proiect care chiar are o finalitate practică dar și dorința de documentare și explorare a limbajului
de programare C# precum și tehnologia programării orientată pe obiecte și a bazelor de date.
Alături de profesorul coordonator care are pregătirea necesară și resursele necesare pentru ați
permite să lucrezi și să extinzi un pachet software folosit de mii sau chiar sute de mii de oameni
din întreaga lume, pot spune că am avut parte de o experiență fructuasă și tot suportul necesa r
pentru finalizarea proiectului.
39
Ca și aplicabilitate și exemplu de integrare a unei astfel de aplicații am folosit mediul de
dezvoltare Visual Studio 2012, iar ca server de stocare a bazelor de date am ales sa folosesc SQL
Server 2012. Structura lucrării este alcătuită din c inci ferestre principale
(Autentificare/Înregistrare , Cautare, Calculator, Export Date și Ajutor), fiecare fereastră (form)
dispu ne de o clasă proprie (Starea1Autentificare, Starea2Calculator, Starea3ExportDate,
Starea4Ajutor, Starea6C autare ) care extind e o clasă abstractă numită Stare .
Aplicația are la bază o matrice de tranziție care menegeriază acesul dintr -o fereastră în
alta precum și o clasă abstra ctă Stare care conține mai multe metode abstracte care sunt
implementate în fiecar e clasă corespunzătoare ferestrei respective. Aplicația „Reinvestirea
profitului unei firme în baza materială” oferă suport tehnic unei firme care dorește să investească
în folosul angajațiilor o anumită sumă de bani în vederea modernizării birourilor, ast fel
furnizorul de echipamente trimite firemi o oferta avantajoasă cu produse în format Excel dupa
cum urmează: cod_produs | denumire_firma | pret | cantitate | tip_produs. Aplica ția verifică dacă
toate birourile pot fi modernizate, iar în caz afirmativ va genera o soluție astfel încât suma
ramasă să fie minimă. Dacă nu există o soluție se vor moderniza un număr maxim de birouri în
ordinea priorității astfel încât suma ramasă să fie minimă.
Ca si obiective urmărite în realizarea algoritmului de calcul aș pu tea enumera
următoarele:
Un birou poate fi modernizat numai complet;
Produsele mai scumpe vor fi cumpărate pentru birourile cu prioritate mai mare;
Aplicația se va folosi și anul următor – deci poate fi îmbunătațită cu cazuri noi;
Un birou primește un singur obiect din fiecare cod.
3.2. Paginile aplicației
3.2.1 . Logarea în aplicație
Un utilizator care va urma să folosească aplicația trebuie să dețină un profil personal sau
să iși creeze unul, format dintr -un nume de utilizator, parolă, nume, prenume și email, care vor fi
introduse pe al doilea tab page intitulat Autentificare din pagina de logare (Figura (3.1)). Pentru
creearea unui nou profil este necesară completarea tuturor câmpurilor cu, care au următoarea
structură:
Nume utilizator – numele util izatorului – pot fi introduse doar caractere alfa –
numerice; câmp obligatoriu.
40
Parola – parola utilizatorului necesară logării în aplicație – pot fi introduse doar
caractere alfa -numerice: câmp obligatoriu.
Nume – reprezintă numele utilizatorului necesar exportării datelor prin email – pot fi
introduse doar caractere; câmp obligatoriu.
Prenume – prenumele utilizatorului care de asemenea este utilizat exportării datelor
prin email; câmp obligatoriu.
Email – e-mailul utilizatorului care va reprezenta e -mailul de pe care se vor exporta
datele; câmp obligatoriu.
Figura 3.1 . Pagina de logare (Inregistrare).
Câmpul ”Email” conține un event de tipul ”KeyUp” care după fiecare caracter introdus
respectiv șters va verifica dacă e -mailul intodus este un email sau nu. Validarea e -mailului se
face prin colorarea fontului cu verde respectiv roșu în cazul în care nu es te valid. Notarea (3.1)
din Anexe reprezintă funcția de validarea folosită în această aplicație.
Dupa completarea campurilor pentru înregistrare și crearea profilului, utilizatorul se
poate loga. Pentru intrarea în aplicație este necesara completarea celor două câmpuri de pe tab
page -ul Autentificare și selectarea unei obțiuni pe care dorim, aceasta fiind obligatorie pentru a
ne putea loga în aplicație (Figura (3.2)).
41
Figura 3.2 . Pagina de logare (Autentificare).
Dacă cele două intrări din câmpuri sunt înregistrate în baza de date ca fiind utilizator cu
dreptul de a intra și a folosi aplicația, iar numele de utilizator și parola sunt corecte, Atunci se va
deschide aplicația cu fereastra selectată din G roupB ox-ul Opțiuni.
3.2.2 . Căutarea și introducerea datelor
În această fereastră vor putea introduce datele necesare selectiei produselor de care
utilizatorul are nevoie , pentru ca aplicația să ne poată genera soluția dorită .
Structura ferestrei:
Încărcare date – în urma acționării acestui buton care se regăsește în cloțul stânga
sus, aplicația va creea un OpenFileDialog care va afisa o fereastră de căutare. După
ce fișierul a fost încărcat aplicația va prelua doar coloana ”tip_produs” din fișierul
încărcat și va memora toate produsele grupate într -un DataTable . Notarea (3.2) din
Anexe. Există posibilitatea de a:
– Încărca doar fișiere Excel.
– Renunțarea la încărcarea unui nou fișier și întoarcerea în fereastra
principală.
– Încărca fișiere Excel care au doar formatul : cod_produs | denumire_firma |
pret | cantitate | tip_produs.
42
Introducere număr de birouri – setează numărul de birouri care vor fi modernizate.
Posibilități și restricții:
– Pot fi introduse doar caractere numerice.
– Este un câmp obligatoriu, prin necompletarea lui aplicația generând
apari ția unui mesaj de eroare cu textul ”Numărul de birouri nu a fost
setat”.
Setare număr de produse pe birou – setează numărul de produse cu care va fi
modernizat fiecare birou în parte. Roluri și restricții:
– Permi te accesul la DataGridView.
– Se populează automat la fiecare încărcare a unui fișier în funcț ie de
numărul de produse existente în DataGridView .
– Nesetarea unui număr de produse pe birou nu va permite trecerea la
fereastra ”Calculator”, aplicația generând un mesaj de eroare cu textul ”
Nu a -ti selectat numărul de produse”.
– Nu permite modificarea datelor afișate în interiorul acestui câmp.
Selectarea produselor din DataGridView – este un element de control grafic care
prezintă o viziune asupara unui tabel de date. Va conține o nouă coloană de tip
ChechBox (activ / inactiv), numită ”Adaugat” destinată selectării produselor. Roluri
și restricții:
– Permite selectarea și deselectarea produselor pe care utilizatorul dorește să
le achiziționeze.
– Se populează automat cu produsele încărcate în DataTabel -ul la încărcarea
fișierului Excel.
– Numărul de produse selectate va trebuii să fie aferent câmpului ”Selectaț i
numărul de produse pe birou”.
– Selectarea unui număr mai mic de produse decât numărul de produse pe
birou nu va permite trecerea la fereastra ”Calculator”, aplicația generând
un mesaj de eroare cu textul ”Nu a -ți selectat suficiente produse”.
43
OK – trecerea la pasul următor – ne va permite trecerea la fereastra ”Calculator” sau
”Ajutor” în funcție de opțiunea pe care utilizatorul a ales -o.
În cazul alegerii opțiunii ”Calculator”:
– Se va verifica dacă numărul de produse active din DataGridView este
aferent celui selectat în combobox -ul destinat selectării numărului de
produse pe birou.
– Dacă v erificarea va fi realizată cu succes aplicația va prelua din fișierul
Excel încărcat toate produsele aferente coloanei ”tip_produs” care sunt
active și se vor introduce în baza de date.
În cazul alegerii opțiunii ” Ajutor ”:
– Nu este impusă nicio restricție pentru a putea trece pe fereastra ”Ajutor”.
Figura 3.3 . Pagina de căutare și introducere a datelor.
44
3.2.3 . Fereastra Calculator
La afișarea acestei ferestre aplicația va popula noul DataGridView cu produsele ordonate din tr-un
DataTable acesta conținând produsele din baza de date, tabelul va conține două noi coloane ”Adaugat”
și ”ID” (Figura (3.4)).
Structura ferestrei:
Listarea produselor în DataGridView – va lista toate produsele din baza de date care au fost
introduse în fereastra ”Cauta”. Roluri și restricții:
– Nu permite adaugare, ștergerea și modificarea elementelor listate în
DataGridView.
Introducere profit – reprezintă suma pe care utilizatorul trebu ie să o introducă și dorește să o
investească în folosul angajațiilor prin modernizarea birourilor. Roluri și restricții:
– Pe baza sumei introduse se va genera soluția finală.
– Pot fi introduse doar caractere numeric.
– Completarea câmpului este obligatorie, neintroducerea unei sume generând un
mesaj de eroare cu textul ” Nu a -ti introdus profitul ”.
Afișarea restului – este destinat informării și generării restului în cazul în care programul a
generat o soluție astfel încât suma rămasă să fie minimă. Roluri și restricții:
– Datele afișate în acest câmp nu pot fi modificate sau șterse.
Butonul calculează – în urma acționării butonului care se regăsește în dreapta
câmpurilor ”Profit” și ”Rest”, acesta are ca rol apelarea mai multor funții care vor genera
soluți a finală. Roluri și restricții:
– La ac ționarea butonului se va verifica dacă câmpul profit a fost completat,
necompletarea acestuia generând un mesaj de eroare cu textul ” Nu a -ti
introdus profitul”.
– La fiecare generare a unei soluții va completata câmpul ”Rest” cu suma
ramasă din profitul introdus.
45
Figura 3.4 . Fereastra Calculator.
Structura generala a funcțiilor utilizate pentru generarea soluției:
VerificaCantitati() – verifică dacă există suficiente cantități pentru a moderniza atatea
birouri cât dorește utilizatorul. Notarea (3.3) din Anexe. Principiu de funcț ionalitate:
– Se indentifică câte ti puri de produse exista în listă/ tabel, tipul produsului fiind dat
de coloana ”ID”.
– Pentru fiecare tip de produs se reține intr -un DataRow toate produsele de ac el tip
(spre exemplu toate produsele care au ID=1) și se parcurge printr -un for toate
produsele salvate la pasul curent în DataRow.
– Pe parcursul parcurgerii produselo r din DataRow se memoreaza într -o variabilă
toate cantitățile existente pentru tipul respectiv de produse.
– La finalul parcurgerii se verifică daca cantitatea totala de produse pentru tipul
respectiv este mai mică decăt numărul de birouri pe care utilizator ul dorește să le
modernizeze, în caz afirmativ se va afișa mesajul de eroare ”Nu exista suficiente
produse pentru toate birourile”.
46
IaProdus(int ID, int cantitate) – completează coloana ”Adaugat” cu produsele care vor fi
achiziționate. Notarea (3.4) din Anexe. Principiu de funcționalitate:
– Salvează într -un DataRow toate produsele care au ID -ul egal cu ID -ul primit ca
parametru.
– Se parcurg datele salvate în DataRow și se verifică la fiecare pas dacă cantitatea
de produse pentru produsul respectiv este ma i mare decât cea de care are nevoie
programul, în caz afirmativ el va popula pe coloana ”ID” în dreptul produsului
canitatea disponibila, restul de cantitate de care programul va mai avea nevoie
fiind completată cu produse de la pasul următor.
– La fiecare a dăugare a unuia sau mai multor produse se va reține valoarea totală a
acestora.
MutaProdus(int ID) – această funcție are ca rol eliminarea unui produs mai ieftin din cele
adăugate anterior și adaugarea unui nou produs mai scump . Notarea (3.5) din Anexe.
Principiu de funcționalitate:
– Salvează într -un DataRow toate produsele care au ID -ul egal cu ID -ul primit ca
parametru.
– Parcurge produsele din DataRow și pentru fiecare verifică dacă conține pe
coloana ”ID” elemente întregi mai mari decât zero. În cazul a firmativ funcția va
trece la următorul produs si va adăuga un produs la coloana ”ID” și va elimina
unul de la produsul anterior și va memora linia pe care s -a produs noua adăugare
într-o variabilă numită ”mutat”.
AnulareMutare() – anulează adăugarea unu i produs în cazul în care adaugarea lui duce la
depășirea sumei de profit introdusă de utilizator. Notarea (3.6) din Anexe. Principiu de
funcționalitate:
– Salvează într -un DataRow toate produsele care au ID -ul egal cu ID -ul primit ca
parametru.
– Pe linia me morată în variabila ”mutat” se va elimina un produs din coloana ”ID”
respectiv pe linia anterioara se va adauga un produs.
CalculSuma() – este funcția care calculează suma totală a tuturor produselor care au fost
adăugate pe coloana ”ID” in vederea achi ziționării. Notarea (3.7) din Anexe. Principiu de
funcționalitate:
– Se parcurge lista/tabelul cu toate produsele cu ajutorul unui for .
47
– La fiecare pas se retine într -o variabilă prețul înmulțit cu ID -ul reprezentând
suma totala a produselor adăugate pe coloana ”ID”.
Calcul(int Suma) – această funcție este funcția principală, în interiorul ei apelându -se toate
funcțiile descrise mai sus, și generează soluția finală în funcție de suma de bani pe care
utilizatorul o introduce. Notarea (3.8) din Anexe. Prin cipiu de funcționalitate:
– Se populează toate liniile de pe coloana ”ID” cu zero.
– Se parcurge printr -un for în funcție de numărul de produse pe birou si se apelează
funcșia IaProdus() aceasta returnând suma produselor care au fost adaugate și
fiind salvată într-o nouă variabilă. La fiecare pas se verifică daca suma din noua
variabilă depășește profitul pe care funcția îl primește ca parametru. În acest caz
se va reapela funcșia Calcul() și se va calcula pentru un numă de birouri mai
mic.
– În cazul în care s uma produselor adăugate nu depășește profitul primit ca
parametru funcția va continua să adauge produse mai scumpe și să elimine din
cele mai ieftine prin apelarea funcției MutaProdus().
– După apelarea funcției MutaProdus() se va apela funcția CalculSuma () care va
verifica dacă suma produselor adăugate depășește profitul.
– În cazul în care profitul este depășit se va apela funcția AnulareMutare() .
3.2.4. Fereastra Export Date
La afișarea acestei ferestre utilizatorul are două opțiuni pentru a exporta datele din
fereastra ”Calculator”. Prima opțiune este aceea de a salva datele direct în calculator, a doua opțiune fiind
de a le trimite prin email unui destinatar pe care utilizatorul il dorește. (Figura (3.5)).
Structura ferestrei:
Exportarea datelor di rect în calculator – în urma acționării acestui buton care se
regăsește în cloțul dreapta sus, aplicația va creea un SaveFileDialog care va afisa o
fereastră de salvare fițiere. Permisiuni și resticții:
– Utilizatorul pote să aleagă directorul în care fișierul Excel va fi salvat.
– Fișierul poate fi salvat cu orice nume dorește utilizatorul.
– Singura extensie cu care fișierul poate fi salvat este (.xls).
48
Figura 3.5 . Fereastra Export Date.
Exportarea datelor prin email – în urma acționării butonului din parta stângă jos (plicul
galben cu sageată verde) aplicația va colecta datele din câmpurile regăsite deasupra butonului
și va trimite un email care va conține fișierul Excel cu datele din fereastra ”Calculator”.
Permisiuni și resticții:
– Utilizatorul poat e folosi e -mailul aferent profilului cu care s -a logat din lista
câmpului ”Email personal” sau poate introduce un alt email in același câmp.
Completarea acestui câmp este obligatorie ca e-mailul să poată fi trimis.
– Este necesară introducerea parolei reale a e-mailului de pe care utilizatorul
dorește să trimită datele. În cazul necompletării sau introducerea unei parole
greșite programul va afișa mesajul de eroare ”Datele introduse nu sunt corecte”.
– Câmpul ”Email destinatar” reprezintă e -mailul destinatariului către care
utilizatorul dorește să trimită datele completarea lui fiind obligatorie.
– La trimitere numele și prenumele utilizatorului vor fi preluate din profilul cu care
utilizatorul s -a logat astfel e -mailul trimis va afișa în loc de mesaj ul ”No name”
numele și prenumele utilizatorului.
49
3.2.5 . Fereastra Ajutor
La afișarea acestei ferestre utilizatorul va fi întâmpinat de un manual de instrucțiuni al
aplicației . În această fereastră la secțiune ”Optiuni” se poate opta pentru ieșirea definitivă din aplcație sau
mergerea pe fereastra ”Căutare” . (Figura (3.6)).
Figura 3.6 . Fereastra Ajutor.
50
3.3. Clasa principală ”Stare” și clasele derivate ale acesteia
3.3.1 . Stare – Clasa abstractă principală
În această clasă sunt declarate toate metodele abstracte care vor fi implementate în clasele
derivate ale clasei ”Stare”. Pe lânga metodele abstracte declarate mai sunt implementate și diverse metode
de verificare după cum se va observă în Notarea (3.9).
Metodele abstracte:
– Afisare
– Citire
– EsteCorect
– Mesaj
– Proces
Funcția executare () implementată în această clasă are rolul de a verifica dacă metoda abstractă
EsteCorect() returnează valoarea true, în caz afirmativ ea va permite accesul la metodele abstracte
Mesaj() respectiv Proces().
3.3.2 . Stare a1Autentificare – Clasa aferentă ferestrei Autentificare
Această clasă va extinde clasa principală Stare și vor fi implementate toate metodele abstracte
aferente clasei Stare.
Structură:
Afisare – această metodă va afișa fereastr a Autentificare aferentă acestei clase.
Citire – această metodă va verifica în baza de date datele introduse în fereastra de logare din
secțiunea autentificare, iar în cazul în care datele sunt corecte se va atribuii unei variabile ok
de tip bool valoarea true. Notarea (3.10).
EsteCorect – această metodă va returna valoarea true dacă variabila ok atribuită la metoda
anterioară este true, iar în caz contrar false .
Mesaj – această metodă va returna un string care va reprezenta mesajul care va fi afișat în
cazul în care metoda EsteCorect va returna valoarea true.
Proces – se va verifica ce opțiune a fost aleasă în fereastra aferentă acestei clase pentru a
putea identifica starea pe care aplicația va terbuii să meargă. Notarea (3.11).
51
3.3.3. Starea 2Calculator e – Clasa aferentă ferestrei Calculator
Această clasă va extinde clasa principală Stare și vor fi implementate toate metodele abstracte
aferente clasei Stare.
Structură:
Afișare – această metodă va citi datele din baza de date care au fost introduse la
fereastra ”Căutare” ele fiind puse într -un DataTable pe baza căruie se vor realiza toate
operațiuniile de generare a solușiei, el conținând două noi coloane:
– Coloana Adăugat – este de tip întreg(int) și va co nține numărul de produse pe
care aplicația îl generează ca soluție în vederea achiziționării.
– Coloana ID – este tot de tip întreg (int), și are ca rol de a identifica fiecare tip de
produs în funcție de colo ana ”tip_produs”.
După popularea Datatabel -ului cu produsele din baza de date se va popula DataGridView -ul
aferent acestei ferestre cu produsele din DataTable și în final se va afișa
fereastra ”Calculator”. Notarea (3.12).
Citire – această metodă va veri fica dacă una din opțiuni a fost aleasă în ambele cazuti
variabila ok va primi valoarea true.
EsteCorect – această metodă va returna valoarea true dacă variabila ok atribuită la metoda
anterioară este true, iar în caz contrar false .
Mesaj – această metodă va returna un string care va reprezenta mesajul care va fi afișat în
cazul în care metoda EsteCorect va returna valoarea true.
Proces – se va verifica ce opțiune a fost aleasă în fereastra aferentă acestei clase pentru a
putea identifica starea pe care aplicația va terbuii să meargă.
3.3.4 . Starea3ExportDate – Clasa aferentă ferestrei Export Date
Afisare – această metodă va afișa fereastra Export Date aferentă acestei clase.
Citire – această metodă va verifica dacă una din opțiuni a fost aleasă în ambele cazuti
variabila ok va primi valoarea true.
EsteCorect – această metodă va returna valoarea true dacă variabila ok atribuită la metoda
anterioară este true, iar în caz contrar false .
52
Mesaj – această metodă va returna un string care va reprezenta mesajul care va fi afișat în
cazul în care metoda EsteCorect va returna valoarea true.
Proces – se va verifica ce opțiune a fost aleasă în fereastra aferentă acestei clase pentru a
putea iden tifica starea pe care aplicația va terbuii să meargă.
3.3.5 . Starea4Ajutor – Clasa aferentă ferestrei Ajutor
Afisare – această metodă va afișa fereastra Ajutor aferentă acestei clase.
Citire – această metodă va verifica dacă una din opțiuni a fost aleasă în ambele cazuti
variabila ok va primi valoarea true.
EsteCorect – această metodă va returna valoarea true dacă variabila ok atribuită la metoda
anterioară este true, iar în caz contrar false .
Mesaj – această metodă va returna un string care va reprezenta mesajul care va fi afișat în
cazul în care metoda EsteCorect va returna valoarea true.
Proces – se va verifica ce opțiune a fost aleasă în fereastra aferentă acestei clase pentru a
putea identifica starea pe care aplicația va terbuii să meargă.
3.3.6 . Starea4Ajutor – Clasa aferentă ferestrei Ajutor
Afisare – această metodă nu va conține nicio implementare și nu va afișa nicio fereastră
deoarece este destinată ieșirii din aplicașie.
Citire – această metodă va conține nicio implementare
EsteCorect – această metodă va returna valoarea true.
Mesaj – această metodă va returna un string care va reprezenta mesajul care va fi afișat în
cazul în care metoda EsteCorect va returna valoarea true.
Proces – se va apela metoda Close() care va închide aplicația.
53
3.3.7 . Starea7Cautare – Clasa aferentă ferest rei Cautare
Afisare – această metodă va afișa fereastra Căutare aferentă acestei clase.
Citire – în această metodă sa va realiza o multitudine de verificări după cum urmează:
– Dacă este selectată opțiunea Calculator se va verifica dacă cele două variabile
globale ValidareProduse și ValidareBirouri conțin valoarea true, în caz afirmativ
variabila ok va primi valoarea true. Cele două variabile globale ValidareProduse
și ValidareBirouri le sunt atribuite valoarea true doar atunci când numă rul de
birouri și produsele dorite din DataGridView au fost selectate corect.
– Dacă este selectată opțiune Ajutor variabila ok va primi valoarea true fară ca
aceasta să îndeplinească vreo condiție.
EsteCorect – această metodă va returna valoarea true dacă variabila ok atribuită la metoda
anterioară este true, iar în caz contrar false .
Mesaj – această metodă va returna un string care va reprezenta mesajul care va fi afișat în
cazul în care metoda EsteCorect va returna valoarea true.
Proces – se va ver ifica ce opțiune a fost aleasă în fereastra aferentă acestei clase pentru a
putea identifica starea pe care aplicația va terbuii să meargă.
3.3.8 . Exemplu
În următorul exemplu este prezentată soluția generată de aplicație pe baza pe baza fișierului Excel
din Figura (3.7) acesta presupunând a fi fișierul furnizat de producătorul de electronice pe care utilizatorul
îl va încărca în aplicație . După ce fișiserul a fost încărcat în aplicație în fereastra ”Cautare”, Figura (3.8)
au fost setate numărul de birour i mai exact 7 precum și numărul de produse și anume 4 produse pe birou
pe birou urmată de selectarea din tabel a produselor dorite.
În fereastra ”Calculator” utilizatorul alege să investească suma de 4040 RON aplicația fiind
obligată sa genereze o soluție care să nu depășească suma respecivă. La apăsarea butonului calculează
aplicația generează mesajul de eroare ”Nu aveti suficinete fonduri pentru toate birourile” Figura(3.9),
astfel suma introdusă nefiind suficientă pentru a moderniza 7 birouri aplicația v a genera o soluție pentru
un număr de birouri mai mic respectiv 6 suma introdusă fiind suficientă pentru a moderniza complet 6
birouri.
54
Figura 3.7 . Fișierul oferit de producătorul de electronice.
Figura 3.8 . Selectarea produselor dorite de către utilizator.
55
Figura 3.9 . Soluția generată.
Concluzii
În concluzie lucrarea de fată prezintă tehnologiile utiliziate în realizarea unui astfel de
proiect cât și modul de realizare descris cât se poate de detaliat, cu capturi de ecran și ilustrări de
cod folosite în reali zarea aplicației. Deoarece tema lucrării a fost una destul de interesantă
precum și una foarte practică în viata reală pe viitor doresc să extind cât mai mult posibil
aplicația.
56
Bibliografie
[1] Microsoft , Programare Orient ată pe obiecte și Programarea Vizuală ,
http://www.colegiulbratianu.ro/Diverse/DotNet.pdf
[2] Lucian Sasu . Limbajul C#,
http://www.cs.ubbcluj.ro/~vcioban/Bistrita/Manuale/CursDotNetSassu.pdf
[3] Constantin Gălățan, Susana Gălățan . C# pentru liceu,
http://www.ls -infomat.ro/user/content/e9efcsharp.pdf
[4] Florin Leon, Aplicații de ingineria programării în C#,
http://users.cs.tuiasi.ro/~fleon/books/Aplicatii_de_ingineria_programarii_in_Cs.pdf
[5] Grugu Ramakrishnan, Johannes Gehrke, Database Management Systems,
http://neerci.ist.utl.pt/neerci_shelf/LEIC/3%20Ano/1%20Semestre/Base%20de%20Dad
os/Bibliografia/DMSystems%20 -%203rd%20Ed.pdf
[6] http://cur s.algoritmi.ro/2011/04/14/tp -09
[7] http://andrei.clubcisco.ro/cursuri/2pa/laboratoare/Laborator%202 -3.pdf
[8] http://forum.portal.edu.ro/index.php?act=Attach&type=post&id=2298840
[9] http://bdfr.cs.pub.ro/BD3 -slides.pdf
[10] http://elth.pub.ro/~petrescu/6.Master/Curs3.pdf
[11] http://bdfr.cs.pub.ro/BD2 -txt.pdf
[12] http://blog.zeltera.eu/?p=310
[13] http://www.dotnet -tricks.com/T utorial/netframework/NcaT161013 -Understanding –
%20.Net -Framework -4.5-Architecture.html
[14] https://msdn.microsoft.com/en -US
[15] https://en.wikipedia.org/wiki/Main_Page
[16] http://andrei.clubcisco.ro/cursuri/f/f –
sym/3bd/16.%20Implementarea%20bazelor%20de%20da te%20Microsoft%20SQL%20Se
rverOracle.pdf
57
Anexe
Notare a 3.1: Funcția Validare Email ()
public bool ValidareEmail( string emailString)
{
invalid = false;
if (String.IsNullOrEmpty(emailString))
return false;
emailString = Regex.Replace(emailString, @"(@)(.+)$" , this.DomeniuMapare);
if (invalid)
return false;
return Regex.IsMatch(emailString,
@"^(?("")(""[^""]+?""@)|(([0 -9a-z]((\.(?!\.))|[-
!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0 -9a-z])@))" +
@"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-
z0-9]{2,17}))$" ,
RegexOptions .IgnoreCase);
}
private string DomeniuMapare( Match match)
{
IdnMapping idn = new IdnMapping ();
string numeDomeniu = match.Groups[2].Value;
try
{
numeDomeniu = idn.GetAscii(numeDomeniu);
}
catch (ArgumentException )
{
invalid = true;
}
return match.Groups[1].Value + numeDomeniu;
}
Notare a 3.2: Funcția CitireDateDinExcel1 ()
protected DataTable CitireDateDinExcel1( string FilePath)
{
DataTable dtexcel = new DataTable ();
bool hasHeaders = true;
string HDR = hasHeaders ? "Yes" : "No";
string strConn;
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + FilePath +
";Extended Properties= \"Excel 8.0; HDR=" + HDR + ";IMEX=0 \"";
OleDbConnection conn = new OleDbConnection (strConn);
conn.Open();
DataTable schemaTable = conn.G etOleDbSchemaTable( OleDbSchemaGuid .Tables, new
object[] { null, null, null, "TABLE" });
DataRow schemaRow = schemaTable.Rows[0];
58
string sheet = schemaRow[ "TABLE_NAME" ].ToString();
if (!sheet.EndsWith( "_"))
{
string query1 = "SELECT tip_produs FROM [" + sheet + "] group by
tip_produs" ;
OleDbDataAdapter daexcel = new OleDbDataAdapter (query1, conn);
daexcel.Fill(dtexcel);
}
conn.Close();
conn.Dispose();
return dtexcel;
}
Notarea 3. 3: Funcția VerificaCantitati()
private bool VerificaCantitati()
{
for (int i = 1; i <= nrProdusePeBirou; i++)
{
DataRow[] rows = Global.dataTableProduse.Select( "ID=" + i);
int cantitate = 0;
for (int j = 0; j < rows.Length; j++)
{
cantitate += Convert.ToInt32(rows[j][3]);
}
if (cantitate < this.nr_birouri)
{
MessageBox .Show(null, "Nu exista suficiente produse pentru toate
birourile!" , "ReinvestireProfit ", MessageBoxButtons .OK, MessageBoxIcon .Error);
return false;
}
}
return true;
}
Notarea 3.4: Funcția IaProdus (int ID, int cantitate )
private int IaProdus( int ID, int cantitate)
{
DataRow[] rows = Global.dataTableProduse.Select( "ID=" + ID);
int total = 0;
for (int i = 0; i < rows.Length; i++)
{
if (cantitate > 0 && cantitate > Convert.ToInt32(rows[i][3]))
{
int c = Convert.ToInt32(rows[i][3]);
rows[i][ "Adaugat" ] = c;
cantitate -= c;
total += Convert.ToInt32(rows[i][2]) *
Convert.ToInt32(rows[i][ "Adaugat" ]);
}
else
{
59
rows[i][ "Adaugat" ] = cantitate;
cantitate = 0;
total += Convert.ToInt32(rows[i][2]) *
Convert.ToInt32(rows[i][ "Adaugat" ]);
break;
}
}
return total;
}
Notarea 3.5: MutaProdus (int ID )
private void MutaProdus( int ID)
{
DataRow[] rows = Global.dataTableProduse.Select( "ID=" + ID);
int i = 0, produse_disponibile = 0;
for (i = 0; i < rows.Length; i++)
{
if (Convert.ToInt32(rows[i][ "Adaugat" ]) > 0)
{
i++;
break;
}
}
for (; i < rows.Length && produse_disponibile == 0; i++)
{
produse_disponibile = Convert.ToInt32(rows[i][3]) –
Convert.ToInt32(rows[i][ "Adaugat" ]);
if (produse_disponibile > 0)
{
rows[i – 1]["Adaugat" ] = Convert.ToInt32(rows[i – 1]["Adaugat" ]) – 1;
rows[i][ "Adaugat" ] = Convert.ToInt32(rows[i][ "Adaugat" ]) + 1;
mutat = i;
return;
}
}
}
Notarea 3.6: AnulareMutare (int ID )
private void AnulareMutare( int ID)
{
DataRow[] rows = Global.dataTableProduse.Select( "ID=" + ID);
rows[mutat – 1]["Adaugat" ] = Convert.ToInt32(rows[mutat – 1]["Adaugat" ]) + 1;
rows[mutat][ "Adaugat" ] = Convert.ToInt32(rows[mutat][ "Adaugat" ]) – 1;
}
60
Notarea 3.7: Calcul Suma ()
private int CalculSuma()
{
int total = 0;
for (int i = 0; i < Global.dataTableProduse.Rows.Count; i++)
total += Convert.ToInt32( Global.dataTableProduse.Rows[i][2]) *
Convert.ToInt32( Global.dataTableProduse.Rows[i][ "Adaugat" ]);
return total;
}
Notarea 3.8: Calcul (int Suma )
private void Calcul(int Suma)
{
int total = 0;
for (int i = 0; i < Global.dataTableProduse.Rows.Count; i++)
Global.dataTableProduse.Rows[i][ "Adaugat" ] = 0;
for (int i = 1; i <= nrProdusePeBirou; i++)
{
total += this.IaProdus(i, this.nr_birouri);
if (total > Suma)
{
ValidareFonduri = true;
this.nr_birouri –;
this.Calcul(Suma);
return;
}
}
if (ValidareFonduri == true)
{
MessageBox .Show(null, "Nu aveti suficiente fonduri pentru toate
birourile!" , "ReinvestireProfit" , MessageBoxButtons .OK, MessageBoxIcon .Error);
ValidareFonduri = false;
}
int stop = 0;
while (total < Suma)
{
if (stop == total)
{
break;
}
stop = total;
for (int i = 1; i <= nrProdusePeBirou; i++)
{
this.MutaProdus(i);
total = this.CalculSuma();
if (total > Suma)
{
this.AnulareMutare(i);
total = this.CalculSuma();
}
61
}
}
Global.Rest = Suma – total;
}
Notarea 3.9: Stare – Clasa abstractă principală
public abstract class Stare
{
public virtual bool esteFinala() { return false; }
public static int alege;
public abstract void Afisare();
public abstract void Citire();
public abstract bool EsteCorect();
public abstract string Mesaj();
public abstract void Proces();
public void executare()
{
bool ok = false;
Afisare();
Citire();
ok = EsteCorect();
if (ok)
{
System.Windows.Forms. MessageBox .Show(Mesaj());
Proces();
}
}
}
Notarea 3.10: Starea1Autentificare – Metoda Citire()
public override void Citire()
{
SqlConnection con = new SqlConnection ();
con.ConnectionString = @"Data Source=EDY; Initial Catalog=REINVESTIRE –
PROFIT; Integrated Security=SSPI" ;
con.Open();
string txtNumeUtilizator = f1.tbNumeUtilizator.Text;
string txtParola = f1.tbParola.Text;
string query = "select
u.UserName,u.Password_user,u.FirstName,u.LastName,e.Email from USERS u inner join
EMAIL_DETAILS e on(u.UserName=e.UserName) where u.UserName=@user and
u.Password_user=@paswd" ;
SqlCommand cmd = new SqlCommand (query, con);
cmd.Parameters.Add( new SqlParameter ("@user", txtNumeUtilizator));
cmd.Parameters.Add( new SqlParameter ("@paswd" , txtParola));
SqlDataReader rd = cmd.ExecuteReader();
if (rd.HasRows == true)
{
ok_autentificare = true;
while (rd.Read())
{
nume = rd[ "FirstName" ].ToString();
prenume = rd[ "LastName" ].ToString();
numeutilizator = rd[ "UserName" ].ToString();
}
}
con.Close();
62
}
Notarea 3.11: Starea1Autentificare – Metoda Proces()
public override void Proces()
{
if (f1.rbCautare.Checked == true)
IncarcareAplicatie .starecurenta =
IncarcareAplicatie .tranzitii[ IncarcareAplicatie .starecurenta, 0];
else if (f1.rbAjutor.Checked == true)
IncarcareAplicatie .starecurenta =
IncarcareAplicatie .tranzitii[ IncarcareAplicatie .starecurenta, 1];
f1.Hide();
}
Notarea 3.12: Starea2Calculator – Metoda Afisare()
public override void Afisare()
{
if (Calculator .dgv_produse.DataSource == null)
{
try
{
Global.dataTableProduse = this.CitireDateDinExcel();
Calculator .dgv_produse.DataSource = Global.dataTableProduse;
Calculator .dgv_produse.Columns[0].HeaderText = "Cod produs" ;
Calculator .dgv_produse.Columns[1].HeaderText = "Firma";
Calculator .dgv_produse.Columns[2].HeaderText = "Pret";
Calculator .dgv_produse.Columns[3].HeaderText = "Cantitate" ;
Calculator .dgv_produse.ReadOnly = true;
Global.dataTableProduse.Columns.Add( new DataColumn ("Adaugat" ,
typeof(int)));
Global.dataTableProduse.Colu mns.Add( new DataColumn ("ID",
typeof(int)));
for (int j = 0; j < Global.NumarProduseSelectate; j++)
{
for (int i = 0; i < Global.dataTableProduse.Rows.Count; i++)
{
if (Global.dataTableProduse.Rows[i][ "tip_produs" ].ToString()
== Global.vector[j].ToString())
{
Global.dataTableProduse.Rows[i][ "ID"] = j + 1;
}
}
}
}
catch (Exception ) { }
}
f2.Show();
}
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: INTRODUCERE ………………………….. ………………………….. ………………………….. …………………… 1 1…. [614176] (ID: 614176)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
