Aplicatie Informatica Pentru Evidentierea Activitatii Unei Firme de Comert
UNIVERSITATEA DIN PITEȘTI
FACULTATEA DE MATEMATICĂ-INFORMATICĂ
DOMENIUL DE LICENȚĂ: INFORMATICĂ
LUCRARE DE LICENȚĂ
Coordonator:
Lect. univ. dr . Doru CONSTANTIN
Student:
Viorel-Marian PĂIUȘI
PITEȘTI,2016
UNIVERSITATEA DIN PITEȘTI
FACULTATEA DE MATEMATICĂ-INFORMATICĂ
DOMENIUL DE LICENȚĂ: INFORMATICĂ
APLICAȚIE INFORMATICĂ PENTRU EVIDENȚA ACTIVITAȚII UNEI FIRME DE COMERȚ
Coordonator:
Lect. univ. dr . Doru CONSTANTIN
Student:
Viorel-Marian PĂIUȘI
PITEȘTI,2016
Cuprins
Introducere
Lucrarea de față își propune să prezinte principalele aspecte teoretice și practice privind o aplicație informatică pentru evidența activității unei firme de comerț.
Ținând cont de obiectivele esențiale propuse spre a fi realizate , prezenta lucrare este structurată pe trei capitole.
Primul capitolul poate fi considerat unul de introducere în baze de date.Sunt definite conceptele de bază de date , proiectare a bazelor de date , limbajul de programare SQL,tipuri de date , funcții , comenzi pentru crearea tabelelor, comenzi de interogare.
Capitolul doi este dedicat platformei .Net , limbajului de programare C# și tehnologiilor LinqToSQL și modelului arhitectural MVVM (Model View ViewModel).Sunt prezentate elemente precum cuvinte cheie ale limbajului C# , tipuri de date ,tablouri și instrucțiuni de selecție ,ciclare sau de salt.În partea dedicata tehnologiei LinqToSQL sunt prezentați operatorii Linq , obținerea unui context de date și operațiile permise prin intermediul Linq.
Ultimul capitol este dedicat aplicației informatice privind evidența activității unei firme de comerț.Acest capitol cuprinde descrierea aplicației , proiectarea aplicației ce cuprinde proiectarea bazei de date , implementarea bazei de date și a aplicației C# și descrierea funcționalității aplicației.
Lucrarea are la bază manuale și studii de specialitatea , acestea fiind menționate în bibliografia aferentă.
Capitolul 1
Notiuni fundamentale despre baze de date
1.1 Proiectarea bazelor de date
O bază de date este o colecție de date centralizate, creeată și menținută computerizat, în scopul prelucrării datelor în contextul unui set de aplicații. Prelucrarea datelor se referă la operațiile de introducere, ștergere, actualizare și interogare a datelor.
Proiectarea unei baze de date constă în creearea schemei conceptuale (logice) si fizice a acesteia, astfel încât să răspundă cerințelor utilizatorilor pentru un anumit set de aplicații.
1.1.1 Proiectarea conceptuală a bazelor de date
În faza de proiectare conceptuală a bazelor de date se proiectează schema conceptuală și schemele externe ale bazei de date.
Proiectul conceptual de nivel înalt se realizează pe baza cerințelor definite în prima etapă de proiectare și se reprezintă, în general printr-o diagramă Entitate-Asociere.
Modelul Entitate-Asociere
Modelul Entitate Asociere este un model conceptual al unei baze de date , care definește mulțimile de entități și asocierile dintre ele , dar nu impune nici un mod specific de structurare și prelucrare a datelor.Elementele esențiale ale modelului Entitate-Asociere sunt entitățile și asocierile (relațiile) dintre acestea.
Entitățile modelează clase de obiecte concrete sau abstracte despre care se colectează informații, au existență independentă și pot fi identificate în mod unic.Orice entitate este descrisă prin atributele sale.Un atribut este o proprietate care descrie un anumit aspect al unei entități.
O asociere este o legătură între două entități din două sau mai multe mulțimi de entități. Gradul unei asocieri este dat de numărul de mulțimi de entități asociate. Asocierile pot fi binare (de gradul 2, între 2 mulțimi de entități) sau multiple (între mai mult de 2 mulțimi de entități).
Fiind date două entități, E1 și E2, se definesc următoarele asocieri binare:
Asocierea “unu-la-unu” (one-to-one) este asocierea în care unei instanțe a entității E1 îi
corespunde cel mult o instanță a entității E2, și reciproc; se notează cu 1:1.
Asocierea “unu-la-mulți” (one-to-many) este asocierea în care unei instanțe a entității E1
îi corespund zero, una sau mai multe instanțe ale entității E2, dar unei entități E2 îi corespunde cel mult o instanță a entității E1; se notează cu 1:N.
Asocierea “mulți-la-mulți” (many-to-many) este asocierea în care unei instanțe a entității E1 îi corespund zero, una sau mai multe instanțe ale entității E2, și, de asemenea, unei instanțe a entității E2 îi corespund zero, una sau mai multe instanțe ale entității E1; se notează cu N:N.
Modelul relațional al datelor
Modelul relațional al datelor a fost conceput și dezvoltat de Edgar Frank Codd (1923–2003, informatician american de origine engleză) la începutul anilor 1970 și cuprinde trei componente principale: structura datelor, integritatea datelor și prelucrarea datelor.
Structura datelor
În modelul relațional al datelor sunt definite noțiunile de atribut, domeniu, relație, schema relației, schema relațională.
Un atribut este un identificator ce descrie o informație memorată în baza de date.
Domeniul unui atribut este o mulțime de valori posibile. Aceste valori sunt de tip similar.
O relație este o submulțime a produsului cartezian a n domenii ale atributelor (n>0).
Elementele unei relații se numesc tupluri.
Într-o relație nu sunt permise tupluri identice.
Relațiile sunt reprezentate sub forma tabelelor bidimensionale în care fiecare rând reprezintă un tuplu și fiecare coloană reprezintă valorile actuale ale tuplurilor dintr-un domeniu al produsului cartezian. Tabelele formează structura logică a modelului relațional.
Pentru o relație (tabel), pot exista trei tipuri de chei.
Cheiea candidat este un ansamblu minimal de atribute(coloane) eventual un singur atribut care permite identificarea fără echivoc a fiecărui tuplu (rând) al relației (tabelului).
Cheiea primară. Pentru fiecare relație se alege o cheie candidat care va fi desemnată ca fiind cheia primară a relației. Celelalte chei candidat, daca există, poartă denumirea de chei alternante. Atributele care compun cheia primară nu pot primi valoarea Null.
Cheiea străină este un ansamblu de atribute al unei relații R1 care în același timp este cheie primară sau alternantă în altă relație R2, nu neapărat distinctă de R1 și care respectă regula integrității referențiale (valorile cheii străine, dacă nu sunt null, se regăsesc printre valorile cheii primare ale relației R2).
Schema relației specifică numele relației, lista de atribute cu domeniile lor și cheia primară a relației.
Schema relațională este alcătuită din mulțimea schemelor relațiilor cu menționarea cheilor străine.
Integritatea datelor
Este dată de corectitudinea informațiilor conținute în baza de date și presupune detectarea, corectarea și prevenirea diferitelor erori. Condițiile de integritate nu permit introducerea în baza de date a unor date incorecte.
Există constrângeri(reguli) de integritate la nivel de domeniu care privesc anumite valori pentru atribute, constrângeri la nivel de tuplu și constrângeri multituplu.
Prelucrarea datelor
Are la bază algebra relațională bazată pe o colecție de operatori ce au ca operanzi relații. Rezultatul aplicării unui operator la una sau două relații (în funcție de aritatea acelui operator) este tot o relație.
Sunt cinci operații de bază care pot fi aplicate relațiilor: reuniunea, diferența, produsul cartezian, proiecția și selecția.
1.2 Limbajul SQL(Structured Query Language)
SQL (limbaj de interogare structurat) este un limbaj de programare folosit pentru manipularea datelor în sistemele de gestiune a bazelor de date , iar la origine este un limbaj bazat pe algebră relațională.Acest limbaj de programare este folosit pentru inserarea datelor, interogări, actualizarea și ștergerea datelor, modificarea și crearea schemelor, precum și controlul accesului la date.
1.2.1. Tipuri de date SQL
În limbajul SQL sunt predefinite mai multe tipuri de date: numeric, șir de caractere, dată, timp.
Tipul numeric include numere întregi de diferite dimensiuni :
-int reprezentat pe 4 octeți, smallint, reprezentat pe 2 octeți;
-numere reale reprezentate în virgulă flotantă, cu diferite precizii : float reprezentat pe 4 octeți și double reprezentat pe 8 octeți.
Tipul șir de caractere permite definirea șirurilor de caractere de lungime fixă char(n) precum și a șirurilor de caractere de lungime variabilă varchar(n). Ambele tipuri pot reprezenta șiruri de maximum n caractere, cu diferența că, pentru șiruri de lungime mai mică decât n, la tipul char(n) se completează șirul cu spații albe până la n caractere, în timp ce la tipul varchar(n) se memorează numai atâtea caractere câte are șirul dat.
Tipurile pentru data calendaristică și timp sunt: date, time, timestamp, interval
1.2.2 Funcții definite in limbajul SQL
Funcțiile definite în SQL sunt împărțite de două categorii: funcții scalare și funcții agregat.
Funcțiile scalare sunt folosite în expresii, care pot să apară în diferite clauze ale instrucțiunilor SQL. Acestea primesc unul sau mai multe argumente și returnează valoarea calculată, sau NULL, în caz de eroare. Argumentele funcțiilor pot fi constante sau valori ale atributelor specificate prin numele coloanelor corespunzătoare. Există mai multe tipuri de funcții scalare SQL: funcții numerice (sin, cos, ln, log etc.), funcții pentru manipularea șirurilor de caractere, funcții pentru dată calendaristică și timp, funcții de conversie.
Funcțiile agregat calculează un rezultat din mai multe linii ale unui tabel.
COUNT-returnează numărul de linii ce îndeplinesc un criteriu
SUM-returnează suma tuturor valorilor dintr-o coloană.
MAX-returnează valoarea cea mai mare dintr-o coloană.
MIN-returnează valoarea cea mai mica dintr-o coloană.
AVG-returnează media valorilor dintr-o coloană.
ALL – indică faptul că agregarea se aplică tuturor valorilor. ALL este opțiunea
implicită.
DISTINCT – specifică faptul că agregarea se aplică doar asupra unei singure instanțe a
fiecarei valori din grup, duplicatele fiind ignorate.
1.2.3 Crearea bazelor de date
Pentru creearea unei baze de date se folosește comanda CREATE DATABASE numele bazei de date.
1.2.4 Instrucțiuni SQL pentru definirea datelor
Crearea tabelelor
Instrucțiunea de creeare a unui tabel este CREATE TABLE numele tabelului și între paranteze rotunde se definesc coloanele tabelului , tipul de date al coloanei și diferite constrângeri pe care datele înregistrate trebuie să le respecte pentru asigurarea corectitudinii bazei de date.
Constrângerile coloanelor si tabelelor sunt opționale.
Constrângerea NULL
Specifică faptul că sunt permise valori Null pentru coloana respectivă.Constrângerea NULL este implicită.
Constrângerea NOT NULL
Specifică faptul că sunt interzise valorile Null pentru coloana respectivă.
Constrângerea PRIMARY KEY
Impune valori unice și nenule pentru coloana în cauză, iar aceasta va reprezenta cheia primară a tabelului. Un tabel poate avea o singură cheie primară .
Constrângerea UNIQUE
Impune valori unice pentru coloana în cauză, iar aceasta va reprezenta o cheie candidat a tabelului.
Constrângerea IDENTITY
Indică o coloană asociată unui tip de date întreg, pentru care SQL Server generează în mod automat valori incrementale, unice la nivel de tabel.
Constrângerea Foreign key
Constrângerea FOREIGN KEY definește o coloană sau o combinație de coloane ca foreign key și stabilește o relație între o cheie primară și una unică în același tabel sau în tabele diferite numită cheie străină.Constrângerile de tip FOREIGN KEY pot fi definite la nivel de coloană sau tabel.
Constrângerea Check
Definește o restricție pe care trebuie să o satisfacă datele din coloana respectivă. Expresia logică atașată unei constrângeri Check la nivel de tabel poate face referire la orice coloană a tabelului curent.
Modificarea structurii tabelelor
Comanda ALTER TABLE permite modificarea structurii unui tabel.Se pot efectua următoarele tipuri de modificări:
– Modificarea tipului de dată al unei coloane.
Sintaxă: ALTER TABLE nume_tabel
ALTER COLUMN nume_coloană tip_de_date_nou
– Adaugarea unor noi coloane (împreună cu eventuale constrângeri pentru aceste coloane).
Sintaxă: ALTER TABLE nume_tabel
ADD nume_coloană tip_de_date
– Adaugarea unor coloane calculate:
Sintaxă: ALTER TABLE nume_tabel
ADD nume_coloană AS expresie_coloană_calculată
-Ștergerea unor coloane:
Sintaxă: ALTER TABLE nume_tabel
DROP nume_coloană
-Adaugarea unor noi constrângeri :
Sintaxă: ALTER TABLE nume_tabel
ADD constraint denumire_constrângere check(constrângere)
-Adaugarea unei valori implicite pentru o coloană:
Sintaxă: ALTER TABLE nume_tabel
ADD constraint nume_constrângere DEFAULT expresie_coloană for coloană
-Ștergerea unor constrângeri :
Sintaxă: ALTER TABLE nume_tabel
DROP nume_constrângere
Ștergerea unui tabel
Comanda DROP TABLE șterge din baza de date definiția unui tabel împreuna cu indecșii, triggerii si constrângerile asociate. Sintaxa: DROP TABLE nume_tabel
Un tabel poate fi șters daca nu este referit printr-o constrângere de tip FOREIGN KEY.
1.2.5 Instrucțiuni SQL de manipulare a datelor
Comanda INSERT
Pentru a insera noi linii într-un tabel sau într-o vedere se utilizează comanda INSERT. O linie nouă inserată va ocupa în tabel o locație arbitrară .
Sintaxă :
INSERT INTO nume_tabel (denumire_coloană,..) values (expresie,…)
Instrucțiunea SELECT
Instrucțiunea SELECT reprezintă blocul de interogare de bază și selectează informațiile dorite din tabelele bazei de date.
Sintaxa generală a instrucțiunei SELECT este:
SELECT listă_coloane FROM listă_tabele
WHERE [condiție]
[clauze secundare]
Instrucțiunea SELECT conține lista atributelor (coloanelor) unor tabele sau al expresiilor care vor fi selectate și afișate. Coloanele din listă trebuie să aparțină uneia din tabelele specificate în clauza FROM.
Pentru eliminarea liniilor duplicat se introduce funcția agregat DISTINCT.
Dacă lista de coloane este (*), atunci se vor selecta toate coloanele produsului cartezian al tabelelor indicate prin clauza FROM, care îndeplinesc condiția din clauza WHERE.
În clauza SELECT se pot redenumi coloane sau se pot specifica nume pentru expresii, folosind următoarea sintaxă:
SELECT nume_coloană AS nume_coloană_nou,…, expresie AS nume_expresie
FROM listă _tabele [alte_clauze];
Clauza WHERE specifică o condiție ce este folosită pentru a selecta rândurile.Rândurile care nu satisfac condiția specificată prin WHERE sunt eliminate.
Clauza ORDER BY specifică ordinea în care rândurile din rezultat vor fi returnate. Ordinea implicită este ASC (crescatoare), iar pentru o secvența crescatoare valorile null sunt afișate ultimele. Dacă nu se face nici o specificație atunci ordinea de returnare a rândurilor este la latitudinea server-ului.
Prin GROUP BY se constituie subansamble, iar prin clauza HAVING se vor selecta subansamble. Clauza GROUP BY se introduce dacă SELECT include funcții la nivel de grupuri de linii. În acest caz coloanele citate în clauza SELECT vor fi argumente ale funcțiilor de agregare (sum, count, max, min, avg, etc.) sau vor apărea în clauza GROUP BY pentru definirea nivelului de grupare.
Instrucțiunea UPDATE permite actualizarea valorilor coloanelor din una sau mai multe linii ale unui tabel. Aceasta are sintaxa:
UPDATE nume_tabel SET col_1 = expr_1, col_2 = expr_2,… [WHERE condiție];
Clauza WHERE impune ca actualizarea valorilor coloanelor să se execute numai asupra acelor linii care îndeplinesc condiția dată. Dacă este omisă clauza WHERE, atunci vor fi modificate valorile coloanelor din toate liniile tabelului.
Instrucțiunea DELETE permite ștergerea uneia sau mai multor linii dintr-un tabel și are următoarea sintaxă:
DELETE FROM nume_tabel [WHERE condiție];
Din tabel se șterg acele linii care îndeplinesc condiția dată în clauza WHERE. Dacă este omisă clauza WHERE, atunci vor fi șterse toate liniile din tabel.
Operatori SQL
Sunt patru operatori SQL care pot fi aplicați tuturor tipurilor de date: BETWEEN ,IN,LIKE,IS NULL.
Operatorul BETWEEN
Testează dacă valoarea unei expresii se găsește într-un interval de valori.
Operatorul IN
Testează valorile dintr-o listă specificată.
Operatorul LIKE
Utilizând operatorul LIKE putem să selectăm rândurile care se potrivesc cu un model specificat de caractere.
Operatorul IS NULL
Operatorul IS NULL face teste specifice pentru valorile care sunt NULL.
Operatorul EXISTS
Verifică dacă o anumită înregistrare există în rezultatele returnate de o subinterogare
1.2.6 Interogarea datelor din mai multe tabele
Atunci când în clauza FROM a unei comenzi SELECT apar mai multe tabele se realizează produsul cartezian al acestora. De aceea numarul de linii rezultat crește considerabil, fiind necesară restricționarea acestora cu o clauză WHERE.
Atunci când este necesară obținerea de informații din mai multe tabele se utilizează condiții de asociere (join). În acest fel liniile dintr-un tabel pot fi puse în legătură cu cele din alt tabel conform valorilor comune ale unor coloane sau expresii. Condițiile de corelare utilizează de obicei coloanele cheie primară si cheie străină.
Interogarea datelor din mai multe relații folosind tipuri de asocieri
Tipurile de asocieri utilizate în interogarea datelor din mai multe tabele sunt:
– INNER JOIN (asociere internă)
– LEFT OUTER JOIN (asociere externă la stânga)
– RIGHT OUTER JOIN (asociere externă la dreapta)
– FULL OUTER JOIN (asociere externă și la stânga și la dreapta)
Inner join (asociere internă) – rezultatul asocierii include numai acele rânduri din ambele tabele care au valori egale ale cheii de legătură.Sintaxa:
SELECT …FROM tabel_A INNER JOIN tabel_B ON tabel_A.coloana1=tabel_B.coloana2;
Outer join (asociere externă) – este vazut ca opusul lui Inner join. Se includ linii dintr-o tabelă chiar dacă nu există corespondent în cealaltă tabelă. Poate fi de tip:
-left join (asociere la stânga)
Sintaxă:
SELECT …FROM tabel_A LEFT OUTER JOIN tabel_B ON (condiții de join)
Selectează toate rândurile din A, pe care le completează cu informații din B, în masura în care satisfac condițiile de join; acolo unde nu vor exista informații din B, acestea vor fi completate cu NULL.
-right join (asociere la dreapta)
Sintaxă:
SELECT …FROM tabel_A RIGHT OUTER JOIN tabel_B ON (condiții de join)
Selectează toate rândurile din B, pe care le completează cu informații din A, în masura în care satisfac condițiile de join; acolo unde nu vor exista informații din A, acestea vor fi completate cu NULL.
-full join
Sintaxă:
SELECT …FROM tabel_A FULL OUTER JOIN tabel_B ON (condiții de join)
Este un INNER JOIN completat cu toate rândurile din A care nu au corespondent in B si toate rândurile din B care nu au corespondent în A. Acolo unde nu vor exista informații, acestea vor fi completate cu NULL.
Capitolul 2
Descrierea tehnologiilor folosite
2.1 Platforma .NET
.NET este un cadru (Framework) de dezvoltare software ce permite realizarea, distribuirea și rularea atât a aplicațiilor desktop (Windows) cât și a aplicațiilor (WEB). Tehnologia .NET pune la dispoziția utilizatorilor mai multe tehnologii (ASP, XML, OOP, SOAP, WDSL, UDDI, WPF, LINQ) și limbaje de programare (VB, C++, C#, F#) asigurând totodată atât portabilitatea codului compilat între diferite calculatoare cu sistem Windows, cât și reutilizarea codului în programe, indiferent de limbajul de programare utilizat.
.NET Framework este o bibliotecă de clase folosită la momentul execuției aplicațiilor.Fișierele acestei biblioteci trebuie să se gasească neapărat pe un sistem pentru ca un program compilat in .NET să poată rula.
Aplicația Visual Studio.NET, produsă de compania Microsoft este un mediu de dezvoltare utilizat pentru creearea de aplicații in limbajele de programare :Visual Basic(VB) ,C#,C++,F#.
Visual Studio dispune de un editor complex de cod, care se folosește pentru creearea ,modificarea, testarea și rularea codului aplicației.O facilitate a editorului de cod din pachetul Microsoft Visual Studio, foarte utilă programatorilor, este “IntelliSense”(Fig. 2.1.1) . Aceasta oferă autocompletarea codului scris de programator prin combinația de taste CTRL+Spațiu, oferind de asemenea documentație pentru anumite tipuri de date, metode,proprietăți sau clase.
Fig.2.1.1 Intellisense
2.2 Limbajul C#
C# este un limbaj de programare orientat pe obiecte, cu aproximativ 80 de cuvinte cheie și 12 tipuri de date predefinite.Principiile de bază ale programării orientate pe obiecte(Încapsularea, Moștenirea, Polimorfismul,Abstractizarea) sunt elemente fundamentale ale programării in C#.
Cuvintele cheie nu pot fi folosite ca și identificatori . Fig 2.2.1.
Fig 2.2.1 Tabel cuvinte cheie
2.2.1 Tipuri de date
C# prezintă două tipuri de date : tipuri valoare si tipuri referință.Tipurile valoare includ tipurile simple ,tipurile enumerare și structură și au ca principale caracteristici faptul că ele conțin direct datele referite și sunt alocate pe stivă.Tipurile referință includ tipurile clasă, interfață, delegat si tablou ,toate având proprietatea că acest tip stochează referințe către obiecte.
Cuvântul cheie var este un tip de date ce poate reține orice iar compilatorul va deduce tipul pe care l-am atribuit.
2.2.2 Tipuri predefinite
C# conține un set de tipuri predefinite : string,object,tipurile întregi cu semn și fără semn , tipurile bool și decimal.Tipul string este folosit pentru gestionarea șirurilor de caractere codificate Unicode.
Tipul bool este folosit pentru a reprezenta valorile logice true și false.Tipul char este folosit pentru a reprezenta caractere Unicode,reprezentate pe 16 biți.Tipul decimal este folosit pentru calcule în care erorile determinate de reprezentarea în virgulă mobilă sunt inacceptabile , el oferind 28 de cifre zecimale semnificative.
Tipuri predefinite:
object – rădăcina oricarui tip;
string – o secvență de caractere Unicode;
sbyte – tip întreg cu semn, pe 8 biți
short – tip întreg cu semn, pe 16 biți
int – tip întreg cu semn, pe 16 biți
long – tip întreg cu semn, pe 64 biți
byte – tip întreg fără semn, pe 8 biți
ushort – tip întreg fără semn, pe 16 biți
uint – tip întreg fără semn, pe 32 biți
ulong – tip întreg fără semn, pe 64 biți
float – tip cu virgulă mobilă , simplă precizie
double – tip cu virgulă mobilă , dublă precizie
bool – tip boolean
char – tip caracter
decimal -tip zecimal cu 28 de cifre semnificative
2.2.3 Tablouri
O soluție pentru stocarea elementelor având același tip o reprezintă tablourile.Fiecare tablou este un obiect , derivat din clasa abstractă System.Array.Accesul la elemente se face cu ajutorul indicilor care încep de la 0 și se termină la numărul de elemente -1.
Tablouri unidimensionale
Declararea unui tablou unidimensional se face prin plasarea de paranteze drepte între tipul tabloului si numele său.
Exemplu:
int [] v;
Alocarea de spațiu de memorie se face cu ajutorul cuvântului cheie new.
Exemplu:
int [] v=new int [dimensiune];
Proprietatea Length specifică tablourilor returnează numărul de elemente.
Tablouri multidimensionale
În C# există două tipuri de tablouri multidimensionale : rectangulare și neregulate.
Tablouri rectangulare
Un tablou rectangular reprezintă un bloc de memorie n-dimensional.
Exemplu:
int [,] v;
int [,,] v;
Tablouri neregulate
Un tablou neregulat reprezintă un tablou de vectori.
Exemplu:
int [][] v;
2.2.4 Clase
Clasele reprezintă tipuri referință definite de utilizatori.O clasă poate să moștenească o singură clasă și poate implementa mai multe interfețe.
Clasele pot conține constante, câmpuri, metode,proprietăți, evenimente, indexatori, operatori, constructori de instanță , destructori, constructori de clasă.Fiecare membru poate să conțină un nivel de accesare care controlează gradul de acces.
Modificatorii de acces ai membrilor unei clase sunt:
public – poate fi accesat din orice clasă
protected –poate fi accesat doar din clasa din care face parte și din clasele derivate
internal – acces limitat la programul care conține clasa (la aplicația curentă).
private – acces limitat la clasă
Modificatorii de clasă sunt:
public – clasele publice sunt accesibile de oriunde
protected –poate fi folosit pentru clase interioare (tipurile definite sunt accesibile doar în clasa curentă și în clasele derivate.
internal – se poate folosi atât pentru clasele interioare, cât și pentru clase care sunt conținute în aplicația curentă.
private – acces limitat la clasa conținătoare
sealed – o clasă sealed nu poate fi moștenită
abstract – este folosit pentru a definii o clasă care este incomplet definită și care nu poate fi instanțiată
Constanta este un membru al unei clase ce reprezintă o valoare constantă,care poate fi evaluată la compilare.Constantele sunt considerate automat membri statici si pot fi accesate exclusiv prin intermediul numelui de clasă (NumeClasă.NumeConstantă).
Câmpul este un membru ce reprezintă o variabilă asociată unui obiect.
Metoda este un membru care implementează un calcul sau o acțiune.Există metode statice ce pot fi accesate prin intermediul claselor și metode de instanță ce sunt accesate prin intermediul unui obiect.
Proprietatea este un membru folosit pentru a da acces la o caracteristică a unui obiect sau a unei clase.
Evenimentul este un membru care permite unei clase sau unui obiect să pună la dispoziția altora notificări asupra evenimentelor.
Constructorii de instanță sunt membri care implementează acțiuni cerute pentru inițializarea fiecarui obiect.
2.2.5 Instrucțiuni de selecție
Instrucțiunea if
Instrucțiunea if execută o acțiune în funcție de valoarea de adevăr a unei expresii logice.
Exemple:
if (expresie logică) instrucțiune;
if (expresie logică) instructiune; else instrucțiune;
Instrucțiunea switch
Permite executarea unei instrucțiuni în funcție de valoarea unei expresii, care se poate regăsi sau nu într-o listă de valori candidat. Exemplu:
switch (expresie)
{
case etichetă : instrucțiune;
case etichetă: instrucțiune;
…
default: instrucțiune;
}
O etichetă reprezintă o expresie constantă .O instrucțiune poate să și lipsească, iar în acest caz se va executa instrucțiunea de la case–ul următor, sau de la default. Secțiunea default poate să lipsească. Expresia după care se face selecția poate fi de tip : sbyte, byte, short, ushort, int, uint, long, ulong, char, string, enumerare.
2.2.6 Instrucțiuni de ciclare
În C# există 4 instrucțiuni de ciclare: while,do while , for ,foreach.
Instrucțiunea while
Permite executarea unei instrucțiuni atât timp cât valoarea unei expresii logice este adevărată (ciclu cu test anterior).
Exemplu:
while(expresie logică) { instrucțiune };
Instrucțiunea do while
Execută o instrucțiune o dată sau de mai multe ori , cât timp o condiție logică este adevărată .
Exemplu:
do
{
instrucțiune;
}
while(condiție)
Se permite folosirea intrucțiunilor break si continue.
Instrucțiunea for
Execută o secvență de inițializare , după care va executa o instrucțiune atât timp cât o condiție este adevarată(ciclu de test anterior); poate să conțină un pas de reinițializare.Se permite folosirea intrucțiunilor break si continue.
Exemplu:
for(int i=0;i<10;i++)
{
Console.WriteLine(i);
}
Instrucțiunea foreach
Enumeră elementele dintr-o colecție, executând o instrucțiune pentru fiecare element.Colecția poate să fie orice instanță a unei clase care implementează interfața System.Collections.IEnumerable.
Exemplu:
int [] vector={1,2,3,4,5}
foreach( int element in vector)
{
Console.WriteLine(x);
}
2.2.7 Instrucțiuni de salt
Instrucțiunile de salt permit schimbarea ordinii de execuție a codului.
Instrucțiunea break
Produce ieșirea forțată dintr-un ciclu de tip : while,do,for,foreach.
Instrucțiunea continue
Pornește o nouă iterație în interiorul unui ciclu de tip: while, do while , for, foreach.
Instrucțiunea return
Această instrucțiune permite terminarea execuției unei funcții și redarea controlului execuției programului funcției apelante.
2.2.8 Tratarea excepțiilor
O excepție este un obiect care încapsulează informații despre o situație anormală.
Tipul Exception
În C# se pot atunca excepții de tip System.Exception sau derivate ale acestuia.Există o ierarhie de excepții care se pot folosi, sau se pot crea propriile tipuri de excepții.
Aruncarea și prinderea excepțiilor
Aruncarea cu throw
Aruncarea unei excepții se face folosind instrucțiunea throw. Exemplu :
throw new System.Exception();
Prinderea cu catch
Prinderea și tratarea excepției se poate face folosind un bloc try catch.
Exemplu:
try
{
instrucțiuni
}
catch(Exception)
{
}
2.2.9 Colecții
Colecțiile reprezintă un mod de stocare a obiectelor într-o manieră structurată. Framework-ul .Net pune la dispoziție foarte multe clase destinate lucrului cu colecții.Toate aceste clase pot fi gasite în spațiul de nume System.Collections.O colecție este un obiect care implementează una sau mai multe interfețe.
Colecții ordonate
Colecțiile ordonate implementează doar interfața ICollection, iar ordinea în care elementele sunt inserate determină și ordinea în care ele sunt regăsite în colecție.
Exemple:Stack,Queue.
Clasa Stack(Stivă) reprezintă o structură de date de tip “last in first out” (LIFO) ,ultimul element introdus în colecție va fi primul care va ieși din colecție.
Clasa Queue (Coadă) este o structură de date de tipul “first in first out” (FIFO),primul element intrat în colecție este primul element care va ieși din colecție.
Colecții indexate
În aceste colecții accesul la elemente se face prin index,(începând cu 0), similar cu un vector.
Exemplu: ArrayList.
ArrayList este o colecție simplă ce poate stoca orice tip de obiect.
Colecții pe bază de cheie
Colecțiile pe bază de cheie implementează interfața IDictionary.Fiecare element al unei colecții pe bază de cheie este o pereche cheie valoare.
Exemplu:SortedList.
SortedList este o colecție de perechi cheie valoare care sunt sortate după cheie.
Observable Collection
O colecție observabilă este o colecție dinamică de date ce oferă notificări automat când un element este adăugat, șters sau când întreaga colecție este reîmprospătată.Tipul colecției observabile este unul generic și poate fi orice clasă implementată.
Colecția observabilă implementează interfața INotifyPropertyChanged ce oferă o notificare atunci când colecția iși schimbă forma.
Exemplu:
ObservableCollection<ObjectType> colecție =new ObservableCollection<ObjectType>();
2.3 LINQ to SQL
Language Integrated Query (LINQ) permite interogarea unor colecții de date folosind o sintaxă integrată în platforma .NET.Prin intermediul unor operatori se pot interoga colecții de forma: vectori, colecții, clase enumerabile, documente XML, baze de date relaționale.Datele rezultate sunt văzute ca obiecte; are loc o mapare (asociere, traducere) a unor date neobiectuale într-un format ușor de folosit în limbajele obiectuale din cadrul plaformei.
LINQ a fost introdus în versiunea 3.5 a lui .NET Framework și constă într-un set de unelte care sunt folosite pentru lucrul cu date și extensii aduse limbajului.
LINQ to SQL vine cu o soluție pentru accesarea datelor stocate într-un server de baze de date SQL Server.LINQ to SQL definește o asociere între tabelele din baza de date și clase C#, clase numite entități. Suplimentar, se pune la dispoziție o clasă DataContext care mediază comunicarea între baza de date și clasele entitate. DataContext menține starea obiectelor, transformă dintr-un obiect într-o înregistrare și invers.
2.3.1 Operatori LINQ
Operatorii LINQ sunt metode ce lucrează asupra unor secvențe , unde secvențele sunt obiecte a caror tip implementează interfața IEnumerable<T> sau IQueryable<T>.Operatorii LINQ oferă o serie de opțiuni de interogare ce includ filtrări,agregări,proiecții,sortări,conversii, concatenări.
Operatorii de agregare
Operatorii de agregare aplică o funcție peste o secvență.Aceștia sunt :
Average – calculează media peste o secvență
Count – calculează numărul de elemente dintr-o secvență
Max-calculează maximul dintr-o secvență
Min-calculează minimul dintr-o secvență
Sum-calculează suma elementelor dintr-o secvență
Operatorul de Concatenare
Concat -acesta concatenează elementele a două secvențe
Operatorii de Conversie
Operatorii de conversie transformă tipul unei secvențe într-un alt tip.Aceștia sunt:
AsEnumerable –convertește o secvență la un tip IEnumerable<T>
AsQueryable –convertește o secvență la un tip IQueryable<T>
Cast – convertește un element al unei secvențe la un tip specificat
OfType-filtrează elementele unei secvențe returnându-le doar pe cele care au un tip specificat
ToArray-transformă o secvență într-un vector
ToDictionary- transformă o secvență într-un dicționar
ToList – transformă o secvență într-o colecție.
Operatorii de obținere a unui element
Operatorii de obținere a unui element ne returnează un element în funcție de un anumit criteriu.Aceștia sunt:
DefaultIfEmpty-returnează un element implicit daca secvența este goală
ElementAt-returnează elementul de la poziția specificată
ElementAtOrDefault-returnează elementul de la poziția specificată, sau o valoare implicită daca secvența este goală
First-primul element dintr-o secvență
Last-ultimul element dintr-o secvență
Single-returnează elementul din colecție
Operatorul de egalitate
SequenceEqual- verifică dacă doua sevențe sunt egale
Operatorul de grupare
GroupBy – grupează elementele unei secvențe după o cheie
Operatorul de joncțiune
Join – joncțiune interioară a două secvențe
Operatorii de sortare
Operatorii de sortare sunt folosiți pentru a ordona scvențele după anumite criterii.Aceștia sunt:
OrderBy-ordonează crescător elementele unei secvențe pe baza unei chei
OrderByDescending –ordonează descrescător elementele unei secvențe pe baza unei chei
Reverse-inversează ordinea elementelor dintr-o secvență
Operatorii de partițonare
Operatorii de partiționare se referă la împărțirea unei secvențe în doua secțiuni după anumite criterii și returnarea uneia din aceste secțiuni.Aceștia sunt:
Skip-sare peste elementele unei secvențe aflate până la o anumită poziție
SkipWhile-sare peste elementele unei secvențe care îndeplinesc o anumită condiție
Take-ia elementele dintr-o secvență până la o poziție specificată
TakeWhile-ia elementele dintr-o secvență cât timp ele respect o anumită condiție
Operatorii de proiecție
Operatorii de proiecție folosesc la operațiunea de transformare a unui obiect într-o formă nouă specificând proprietățile pe care vrem ca obiectul să le aibă.Aceștia sunt:
Select-definește elementele care se iau în secvență
SelectMany-preia elementele dintr-o secvență ce conține alte secvențe
Operatorii cuantificatori
Operatorii cuantificatori returnează o valoare booleană ce indică daca toate sau o parte din elementele dintr-o secvență satisfac o condiție.Aceștia sunt:
All-verifică daca toate elementele dintr-o secvență satisfac o condiție
Any-verifică daca vreun element al unei secvențe satisface o condiție
Contains-verifică dacă o secvență conține un element
Operatorii de mulțime
Operatorii de mulțime se referă la operații ce pot fi făcute pe o secvență și produc un rezultat ce este bazat pe prezența sau absența unor elemente din secvență.Aceștia sunt:
Distinct –returnează elementele dintr-o secvență eliminând duplicatele
Except –efectuează diferența dintre două secvențe
Intersect- returnează intersecția a două secvențe
Union – produce reuniunea a două secvențe
2.3.2 Obținerea unui context de date
Obținerea obiectului de tip DataContext se poate face adaugând un obiect de tip ”LINQ to SQL”,prin ”Add new item ” la nivel de aplicație precum în (fig. 2.3.2.1.). Vom obține un fișier cu extensia .dbml ce va fi adăugat la aplicație; acesta conține o clasă derivată din DataContext.
Prin adăugarea tabelelor din fereastra de Server Explorer a bazei de date la care dorim să ne conectăm , se vor crea și clasele entitate corespunzătoare tabelelor.(fig 2.3.2.2 și 2.3.2.3).
Fig 2.3.2.1 Adăugarea unui DataContext la aplicație
Fig 2.3.2.2 Selectarea tabelelor pe baza cărora se va construi fișierul DBML
Fig 2.3.2.3 Clasele C# rezultate după adăugarea tabelelor pe suprafața fișierului DBML
Obținerea unui obiect asociat întregii baze de date se face astfel:
Exemplu:
StudentiDataContext studdatacont=new StudentiDataContext();
Obținerea obiectelor de tipul unui tabel se face astfel:
Exemplu:
var allstudents= from student in studdatacont.Studentis
select student;
Orice interogare efectuată cu expresii LINQ poate fi efectuată asupra tabelelor.De exemplu pentru o joncțiune între tabelele Studenti și Clase putem avea :
var studenticlase= from student in studdatacont.Studentis
join clase in studdatacont.Clases
on student.id_clasa equals s.id_clasa
2.3.2 Adăugarea ,modificarea și ștergerea datelor din tabele
Adăugarea unei înregistrări
Pentru adăugarea unei noi înregistrări într-un tabel, vom crea un obiect de tipul clasei DataContext furnizat automat de către DBML.Apelăm metoda InsertOnSubmit pentru adăugarea unei noi înregistrări specificând înainte tabelul în care dorim să adăugăm noua înregistrare. Acțiunea se va executa asupra bazei de date dupa ce va fi apelată metoda SubmitChanges. Exemplu :
StudentiDataContext studdatacont=new StudentiDataContext();
Student stud=new Student();
Stud.id=1;
stud.nume=”Popescu”;
stud.prenume=”Marius”;
studdatacont.Students.InsertOnSubmit(stud);
studdatacont.SubmitChanges();
Modificarea unei înregistrări
Modificarea unei înregistrări se poate face prin obținerea obiectului pe care dorim să îl modificăm, se modifică proprietățile lui și apoi se apelează metoda SubmitChanges pentru contextul de date.
Exemplu:
StudentiDataContext studdatacont=new StudentiDataContext();
foreach(Student stud in studdatacont.Students)
{
if(stud.id==1)
{
stud.nume=”Ionescu”;
studdatacont.SubmitChanges();
}
}
Ștergerea unei înregistrări
Ștergerea unei înregistrări se poate face prin obținerea obiectului pe care vrem să îl ștergem,iar apoi apelând metoda DeleteOnSubmit pe tabelul din care vrem să ștergem.
Exemplu:
StudentiDataContext studdatacont=new StudentiDataContext();
foreach(Student stud in studdatacont.Students)
{
if(stud.id==1)
{
studdatacont.Students.DeleteOnSubmit(stud);
}}
2.4 WPF (Windows Presentation Foundation)
Windows Presentation Foundation(WPF) este un sistem modern de interfață grafică pentru Windows.El aduce o schimbare radicală față de predecesorul lui Windows Form.WPF este cea mai bună soluție pentru a construi o aplicație desktop deoarce oferă separarea părții grafice (interfața cu utilizatorul) de partea logică a aplicației (codul C#).
WPF oferă câteva funcționalități noi față de Windows Form :
O așezare a componentelor pe fereastră la fel ca așezarea celor web – o componentă nu va fi fixată pe o anumită poziție a ferestrei ci va avea o așezare flexibilă în funcție de conținutul anumitor componente.
Un model de desenare bogat în funcționalități – În loc să pictezi pixeli , în WPF poți folosi primitive : figuri de bază , blocuri de text și alte funcționalități grafice.
Un model de text bogat in funcționalități – WPF oferă aplicației Windows abilitatea de a afișa texte cu diferite stiluri ce pot fi puse oriunde pe interfața grafică.Există posibilitatea de a combina textul cu o listă sau un element al interfeței cu utilizatorul.
Stiluri și template-uri – Stilurile îți permit să creezi un format standard pe care îl poți refolosi în altă componentă a aplicației.Template-urile îți permit să schimbi felul în care elementele sunt distribuite , chiar și conținutul unei componente ca butonul.
Comenzile-Se pot folosi pentru a definii un comportament pe care sa îl utilizezi pentru o anumită componentă , poate fi definit într-un loc și folosit și pentru alte componente.
Interfața cu utilizatorul (XAML)- XAML (Extensible Application Markup Language) este folosit pentru a construii interfața grafică .Avantajul este ca interfața grafică este complet separată de codul de programare .
2.4.1 Controale WPF
Controalele sunt componente ale programului Microsoft Visual Studio folosite pentru a crea interfața grafică a unei aplicații.Acestea se găsesc în bara laterală a programului în interiorul meniului Toolbox.
WPF oferă un set bogat de cotroale ce sunt clasate pe mai multe categorii :
Butoane:
Button – un control folosit pentru declanșarea unor evenimente la apasarea unui click pe suprafața lui
Fig 2.4.1.1 Button
ToggleButton – are aceeași funcționalitate ca un buton normal doar că atunci cand apasăm click pe el va ramane apăsat
Fig 2.4.1.2 ToogleButton
CheckBox – este folosit pentru a indică că o valoare este adevarată sau falsă sau starea lui este înca nedeterminată
Fig 2.4.1.3 CheckBox
RadioButton –este un control folosit pentru setarea de valori exclusive într-un set de opțiuni de selecție pe care îl poate avea
Fig 2.4.1.4 RadioButton
Câmpuri de text:
TextBox- este un controler ce conține un text editabil și neformatat
Fig 2.4.1.5 TextBox
PasswordBox – este un controler ce are aceleași proprietăti ca un TextBox , dar ascunde caracterele ce vor fi scrise în el
Fig 2.4.1.6 PasswordBox
Label –este un controler folosit pentru a pune o etichetă pe interfața grafică și are proprietatea read-only ce nu permite editarea lui
Fig 2.4.1.7 Label
TextBlock – are aceleași proprietăți ca un Label dar permite crearea textului personalizat
Fig 2.4.1.8 TextBlock
RichTextBox –este un controler ce permite scrierea pe mai multe linii
Fig 2.4.1.9 RichTextBox
Liste:
ComboBox – este un control ce arată doar valoarea selectată într-o listă pe care o ascunde în mod implicit
Fig 2.4.1.10 ComboBox
ListBox- este o listă ce permite selectarea unei valori
Fig 2.4.1.11 ListBox
ListView- este o listă ce poate fi personalizată
Fig 2.4.1.12 List View
2.4.2 Aranjare în pagină
Aranjarea în pagină a controalelor poate fi simplificată prin folosirea unor panouri pe care se vor pune controalele , iar aranjarea tuturor controalelor vor fi date marginile panoului.
WPF oferă un set de panele:
StackPanel – aranjează controalele în linie orizontală sau verticală
WrapPanel – aranjează controalele în linie orizontală sau verticală , controalele se pliază pe panel pentru a încadra conținutul ,daca nu mai este loc le va trece automat pe urmatoarea linie sau coloană.
DockPanel – plasează controalele în cinci regiuni diferite : sus , jos ,stânga,dreapta sau centru.
Grid-definește o împărțire a spațiului căreia i se alocă în linii și coloane.
2.4.3 XAML
XAML (Extensible Application Markup Language) este un limbaj de marcare folosit pentru instanțierea obiectelor .NET. Rolul XAML-ului este de a construi interfața cu utilizatorul a WPF-ului.
În fisierul .xaml se vor defini aranjarea butoanelor , panourilor și controlul întregii interfețe în aplicația WPF.
Cu tehnologiile tradiționale de interfețe nu era deloc ușor să separi partea grafică de partea logică (partea de cod).Problema cea mai mare a predecesorului său Windows Form este că orice se creează va fi definit în totalitate în cod C#.De fiecare dată când pui un controler pe forma interfeței și o configurezi , Visual Studio generează o clasă ce va corespunde ajustărilor făcute de noi.Un designer grafic nu va avea nici un instrument care să lucreze asupra codului C#.
XAML oferă o separare a interfeței grafice de codul C# , toate elementele definite pe interfața grafică vor fi scrise in limbaj XML sub forma unor taguri.De exemplu pentru definirea unui buton vom scrie un tag <Button> </Button> sau <Button/> ambele variante sunt acceptate de XAML .(Fig 2.4.3.1)
Fig 2.4.3.1 Crearea unui buton in XAML (WPF)
Proprietăți ale controalelor
În XAML un controler definit pe interfață poate avea o serie de proprietăți:
Margin – setează distanța dintre element și marginile ferestrei sau panelului pe care a fost pusă în ordinea următoare Margin=”stânga,sus,dreapta,jos”;
Content – setează conținutul unui controler ce poate conține text;
Width – setează lătimea unui controler;
Height – setează înălțimea unui controler;
VerticalAlignment – setează poziționarea pe verticală care poate fi (în partea de jos,centrat,în partea de sus sau întins pe toată înalțimea ecranului sau panoului pe care a fost definit;
HorizontalAlignment – setează poziționarea pe orizontală care poate fi (în partea de jos,centrat,în partea de sus sau întins pe toată lățimea ecranului sau panoului pe care a fost definit;
Command – se definește o comandă care va fi atribuită unui controler de tip buton;
ItemsSource – se defintește un context de date , o listă a elementelor pe care vrem sa le conțină controler-ul ;
Binding –este o proprietate folosită pentru a specifica sursa de date sau sursa unei comenzi ce menține comunicarea între partea de programare și interfață, notificând interfața la fiecare schimbare ;
IsReadOnly- setează dacă un câmp editabil poate fi modificat sau nu , cu valorile true și false;
Name – numele unui controler
Generarea clasei de implementare a evenimentelor
XAML ne permite să construim o interfață cu utilizatorul, dar pentru a crea o aplicație funcțională, va trebui să găsim o cale să conectăm evenimentele de codul aplicației. XAML simplifică acest lucru generând o clasă unde vor fi definite metodele de gestionare a evenimentelor.
Pentru a crea automat un eveniment pe un controler, de exemplu un buton, vom da dublu click pe controler și ni se va genera un eveniment în clasa din spatele interfeței unde putem implementa comportamentul pe care îl dorim.
XAML permite creearea unui eveniment manual în clasa din spatele interfeței iar apoi il putem atribuii unui controler.
Sintaxa unei metode ce va gestiona evenimentul este următoarea :
private void Nume_Metoda(object sender ,RoutedEventArg e )
{
//codul metodei
}
Pentru a îl atribui unui controler, va trebui să adăugăm acestuia un eveniment și să îi specificăm numele metodei care se va executa pentru acel eveniment. Exemplu :
Click= ”numele_metodei”
DataContext
DataContext este o proprietate a clasei din spatele xaml-ului care are ca valoare implicită clasa respectivă ca și context al datelor , iar pentru a fi folosită o alta clasă din care se va face operația de DataBinding se va seta în clasa din spatele interfeței setând ca DataContext o instanță a clasei pe care o dorim să devină context de date.
Exemplu:
this.DataContext=new Numele_Clasei();
DataBinding
Data binding face conexiunea între un element al interfaței cu utilizatorul și o sursă de date , iar starea lui se va schimba odata cu modificarea datelor .
Interfața oferă două servicii utilizatorilor : prezentarea datelor și interacționarea cu datele.În primul caz citește datele și le afișează iar în al doilea caz implică editarea de date existente ori adăugarea de date noi.
Cu ajutorul proprietății Mode putem seta modul în care vrem să facem legătura.Există mai multe feluri în care se poate face legătura dintre un element al interfeței grafice și o sursă de date:
TwoWay – modificările efectuate pe controlul folosit în interfața grafică se vor aplica si pe sursa de date , iar modificările efectuate asupra sursei de date vor fi aplicate și în controlul folosit;
OneWay- modificările efectuate asupra sursei de date vor fi aplicate și în controlul folosit, iar modificările din controlul folosit nu vor avea efect asupra sursei de date;
Default – în mod implicit este modul TwoWay
Interfața INotifyPropertyChanged
Această interfață ajută la menținerea sincronizării datelor între sursele de date și interfața grafică. Pentru a menține sincronizarea avem nevoie ca la fiecare schimbare a valorii unei proprietăți să notificăm interfața grafică de această schimbare . Pentru a folosi această interfața este nevoie sa o implementăm fig (2.4.3.2) .
Fig 2.4.3.2 Implementarea interfeței INotifyPropertyChanged
2.5 MVVM (Model View ViewModel)
Model View View Model (MVVM) este un model software arhitectural ce facilitează separarea interfeței cu utilizatorul de partea de cod (partea logică a programului).MVVM este bine ordonat și probabil unul din cel mai bun mod de organizare a codului , permite reutilizarea codului creat ,iar structura codului permite o ușoară cale de a realiza mentenanța și testele asupra aplicației.
Modelul MVVM este format din :
Model – cuprinde definirea entitaților cu care se va lucra
View- clasa ce se ocupa cu interfața cu utilizatorul
ViewModel – este clasa ce implementează logica dintre View și Model. Fiecarui View îi corespunde un ViewModel .ViewModel preia datele din model și manipulează datele în formatul cerut de View.ViewModel-ul notifică View-ul dacă datele s-au schimbat cu ajutorul interfeței INotifyPropertyChanged.
În (fig 2.4.3.3) se poate observa cum comunicarea dintre View și date este intermediată de ViewModel care preia cererea de la View , obține datele cu ajutorul Model-ului și întoarce View-ului datele cerute.Legarea la date se poate face și în sens invers , și anume View-ul poate să modifice elemente dintr-o bază de date daca aplicația implementează o astfel de funcționalitate,iar comunicarea va fi asigurată tot de ViewModel care va schimba datele cu ajutorul Model-ului.
Fig 2.4.3.3 Schema Model View ViewModel
Capitolul 3
Aplicație informatică pentru evidența activității unei firme de comerț
3.1 Descriere generală
S-a dorit realizarea unei aplicații pentru a ține evidența activitații unei firme de comerț . Aplicația va permite reținerea într-o bază de date a angajaților (și opțional conturile de logare la aplicație ale acestora ), clienților, produselor ,dar și facturarea și vizualizarea unei facturi.
Pentru angajați se va reține id-ul angajatului,numele,prenumele,departamentul, salariul și opțional ulterior i se poate crea un cont pentru a i se da acces la aplicație.
Aplicația va reține pentru clienti : id-ul clientului , numele , prenumele, cnp-ul și numărul de telefon al clientului.
Produselor li se vor reține : id-ul produsului , numele produsului , categoria , prețul și stocul disponibil.
Aplicația va permite facturarea unui produs sau a mai multor produse pentru un client selectat și vizualizarea facturilor .
Accesul la aplicație se face pe baza unui cont pe care angajați il vor avea , dar cu excepția celor din departamentul de gestiune , un cont al unui angajat normal nu va avea acces la angajații firmei , dar vor putea să emită facturi sau să actualizeze stocuri .
După autentificare , aplicația oferă un meniu de acces la ferestrele angajaților , clienților , produselor, fereastra de facturare sau a facturilor.Există și posibilitatea de a te deconecta de pe clientul curent utilizând butonul de log off.
Aplicația permite diferite operații precum vizualizarea și modificarea : angajaților, clienților sau a produselor , dar și introducerea de produse noi , angajați noi sau a clienților noi.
3.2 Proiectarea aplicației
S-a pornit de la ideea realizării unui sistem informatic pentru gestiunea unei firme de comerț.Pentru a reține informațiile precum clienții, angajații, produsele și facturile a fost necesară dezvoltarea unei baze date.
Proiectarea bazei de date
Pentru realizarea bazei de date a fost necesară stabilirea entităților pe care aplicația noastră le va avea nevoie.Acestea împreuna cu atributele lor sunt :
Angajati(id_angajat,nume,prenume,departament,salariu,id_cont)
Clienti(id_client,nume,prenume,CNP,nr_telefon)
Produse(id_produs,nume_produs,categorie,preț_produs,stoc)
Facturi(id_factura,dată,preț_total)
Cont(id_cont,cont,parola)
Datorită relațiilor de (many to many) mai mulți la mai mulți între entitățile stabilite în prima fază a fost nevoie de creearea tabelelor de legătură ce vor rezolva această problemă ajungânduse la relații de (one to many) unu la mai multi.Astfel s-a ajuns la următoarele entități:
Angajati(id_angajat,nume,prenume,departament,salariu,id_cont)
Clienti(id_client,nume,prenume,CNP,nr_telefon)
Produse(id_produs,nume_produs,categorie,preț_produs,stoc)
Facturi(id_factura,dată,preț_total)
Facturi_Angajati(id_factura_angajat,id_angajat,id_factura)
Facturi_Clienti(id_factura_client,id_client,id_factura)
Facturi_Produse(id_factura_produs,id_produs,id_factura)
Cont(id_cont,cont,parola)
După creearea bazei de date a rezultat diagrama din fig.(3.2.1)
Fig 3.2.1 Diagrama bazei de date
Proiectarea aplicației WPF
Aplicația va avea nevoie de mai multe ferestre care să permit o ușoară înțelegere și utilizare.Se vor crea ferestre pentru: logare ,meniu, operații asupra produselor, clienților, angajaților dar și pentru creearea și vizualizarea facturilor.
3.3 Implementarea aplicației
Pentru realizarea aplicației s-a folosit tehnologia WPF (Windows Presentation Foundation) a programului Visual Studio ce are la bază limbajele C# pentru partea de programare și XAML pentru partea de interfața cu utilizatorul.Cu ajutorul tehnologiei LINQ s-a realizat conexiunea la baza de date și vor fi premise diferite operații în aplicație.
Folosind modelul architectural MVVM(Model View ViewModel) se va separa interfața cu utilizatorul de partea de programare , astfel fiecare fereastra va avea o clasa ViewModel ce va conține partea de implementare pentru operațiile de pe fereastră.
Fiecare operație executată printr-un buton va avea o clasă comandă ce va conține o instanță a sa în clasa ViewModel , ce va fi legată la acel buton.
Fereastra de logare
Pentru realizarea ferestrei de logare s-a început cu partea interfeței cu utilizatorul și s-au creat două etichete una pentru cont si alta pentru parolă , în dreptul etichetei contului s-a creat un TextBox iar în dreptul etichetei parolei un PasswordBox.Pentru autentificare s-a creat un buton Logare ce va verifica dacă contul si parola sunt valide.Acestea au fost realizate în cod XAML (fig 3.3.1)
Fig 3.3.1 Codul XAML
Partea de programare a fost realizată conform modelului architectural MVVM într-o clasă ViewModel ce conține partea de implementare a funcționalități aplicației.
A fost implementată o metodă în clasa ViewModel (fig 3.3.2) a ferestrei ce ne va returna true dacă contul și parola există în baza de date sau false dacă nu există. Pentru legarea la butonul din interfață a fost creată o noua clasă LoginCommand ce va implementa interfața ICommand , clasă a carei instanță va fi legată la butonul Logare definit pe interfața cu utilizatorul.
Fig 3.3.2 LoginViewModel
Clasa LoginCommand (fig 3.3.3) ce implementează interfața ICommand conține trei metode CanExecute,Execute ,CanExecuteChanged .Metoda CanExecute va determina când va putea fi activ butonul de Logare , va returna true daca ambele câmpuri sunt completate sau false daca unul dintre câmpuri este gol.În metoda Execute vom verifica cu ajutorul metodei (VerificaCont) din clasa LoginViewModel dacă contul există sau nu.Dacă va exista vom crea o fereastră de meniu dacă nu vom returna mesajul: Cont sau parola incorectă . Metoda CanExecuteChanged ajută la reevaluarea condițiilor din CanExecute. Va fi trimisă instanța curentă a ViewModelului ca paramentru la instanțierea clasei LoginCommand pentru a putea folosi proprietățile și metodele publice.
Fig 3.3.3 Metodele Execute și CanExecute ale clasei LoginCommand
Fereastra Meniului Principal
Pentru realizarea ferestrei meniului principal s-a folosit un grid ce împarte fereastra în rânduri și coloane.S-au definit patru lini și două coloane .Pe prima linie și întinsă pe ambele coloane s-a creat o bara de status ce va conține numele contului logat și un buton de log off.
Pe restul liniilor rămase , pe fiecare dintre acestea s-au definit câte 2 butoane , ce oferă posibilitatea intrări în ferestrele definite pentru clienți,angajați,produse,facturi sau ferestrei de facturare și posibilitatea închideri aplicației.Acestea au fost realizate în cod XAML (fig.3.3.4)
Fig 3.3.4 O parte din codul XAML al ferestrei meniu
Fiecarui buton creat i-a fost legată o comandă din clasa ViewModel a ferestrei cu instanța comenzi corespunzatoare fiecarui buton.
Fereastra Produse
Pentru realizarea ferestrei de gestionare a produselor s-au folosit : etichete pentru controalele folosite , un ListView pentru afișarea produselor , un ComboBox pentru a sorta produsele din ListView după categoria selectată în combobox, TextBox-uri pentru a putea modifica produsul selectat , și butoane de Update pentru a salva datele modificate ,Delete pentru a șterge produsul selectat ,AdaugăProdus pentru a adăuga un produs nou și Inapoi pentru reîntoarcerea la meniul principal.Aceastea au fost realizate în cod XAML fig(3.3.5).
Fig 3.3.5 O parte din codul XAML al ferestrei produse
Partea de programare a ferestrei a fost realizată într-o clasă ViewModel ce reprezintă contextul de date al ferestrei, orice ce legare ( bind) este facută la o proprietate sau o listă din ViewModel.
Popularea ListView-ului cu produse se face cu ajutorul proprietăți ListaProduse de tip ObservableCollection , colecție ce implementează automat interfața INotifyPropertyChanged ce notifică interfața atunci cand colecția s-a schimbat.Metoda GetProduse() ( fig 3.3.6.) va fi apelată de fiecare dată când ComboBox-ul pentru categorii iși schimbă valoarea.
Fig 3.3.6 Metoda de încărcare a produselor
Fereastra Angajați
Pentru realizarea ferestrei de gestionare a angajaților s-au folosit : etichete pentru controalele folosite , un ListView pentru afișarea angajaților, TextBox-uri pentru a putea modifica caracteristicile angajatului selectat , și butoane de Update pentru a salva datele modificate ,Delete pentru a șterge angajatul selectat ,AdaugăAngajat pentru a adăuga un angajat nou și Inapoi pentru reîntoarcerea la meniul principal.Aceastea au fost realizate în cod XAML (fig 3.3.7)
Fig 3.3.7 O parte din codul XAML al ferestrei angajați
Partea de programare a ferestrei a fost realizată într-o clasă ViewModel ce reprezintă contextul de date al ferestrei, orice ce legare este facută la o proprietate sau o listă din ViewModel.Aplicația permite și gestionarea conturilor iar accesul la acestea va fi permis doar angajaților din departamentul Gestiune.
Popularea ListView-ului cu angajați se face cu ajutorul proprietăți ListaAngajati de tip ObservableCollection , colecție ce implementează automat interfața INotifyPropertyChanged ce notifică interfața atunci cand colecția s-a schimbat.Metoda Incarca() (fig 3.3.8) va popula lista observabilă cu angajați iar aceasta va fi legată la ListView-ul din XAML.
Fig 3.3.8 Încărcarea listei cu angajați
Fereastra Clienți
Pentru realizarea ferestrei de gestionare a clienților s-au folosit : etichete pentru controalele folosite , un ListView pentru afișarea clienților, TextBox-uri pentru a putea modifica caracteristicile clientului selectat , și butoane de Update pentru a salva datele modificate ,Delete pentru a șterge clientul selectat , AdaugăClientului pentru a adăuga un client nou și Inapoi pentru reîntoarcerea la meniul principal.Aceastea au fost realizate în cod XAML (fig 3.3.9)
Fig 3.3.9 O parte din codul XAML al ferestrei clienților
Partea de programare a ferestrei a fost realizată într-o clasă ViewModel ce reprezintă contextul de date al ferestrei, orice ce legare este facută la o proprietate sau o listă din ViewModel.
Popularea ListView-ului cu clienți se face cu ajutorul proprietăți ListaClienti de tip ObservableCollection , colecție ce implementează automat interfața INotifyPropertyChanged ce notifică interfața atunci cand colecția s-a schimbat.Metoda Incarca() (fig 3.3.10) va popula lista observabilă cu clienți iar aceasta va fi legată la ListView-ul din XAML.
Fig 3.3.10 Metoda de încărcare a clienților în listă
Fereastra Facturare
Pentru realizarea ferestrei de facturare s-au folosit etichete pentru controalele folosite, ListView-uri pentru afișarea produselor , clienților și produselor adăugate pe factură,ComboBox-uri , unul pentru selectarea angajatului ce va emite factura , unul pentru sortarea produselor după o categorie și unul pentru a selecta cantitatea produsului ce va fi adăugat pe factură,TextBox-uri pentru identificarea produsului selectat și unul pentru afișarea prețului total al facturii și butoane pentru adăugarea unui client nou,adăugarea unui produs pe lista folosită pentru factură și ștergerea unui produs aflat pe factură și un buton pentru facturare . Acestea au fost realizate în limbajul XAML ( fig 3.3.11)
Fig 3.3.11 O parte din codul XAML al ferestrei facturare
Partea de programare a ferestrei Facturare a fost realizată într-o clasă ViewModel, fiind setată ca și context de date al ferestrei.S-au dezvoltat metode pentru încărcarea listei de clienți, încarcarea listei de produse după o anumită categorie selectată , încarcarea angajaților într-un ComboBox pentru a fi selectat angajatul ce va emite factura.Pentru butoane au fost dezvoltate clase ce implementează interfața ICommnd a caror instanță va fi legătura la butoanele din interfața cu utilizatorul.
Pentru realizarea listei de produse de pe factură s-au implementat butoanele de adăugare și de ștergere a produselor de pe listă .Odată selectat un produs de pe lista de produse el poate fi adăugat pe lista de produse a facturii cu ajutorul butonului adaugă .
Pentru a șterge un produs de lista de produse a facturii , se va selecta produsul de pe lista produselor de pe factură și se va utiliza butonul de ștergere.
Adăugarea produsului pe listă va putea fi facută doar dacă cantitatea va fi selectată iar aceasta nu depășește stocul (fig 3.3.12 și fig 3.3.13).
Fig 3.3.12 Prima parte a codului definit pentru butonul de adăugare a unui produs pe factură
Fig 3.3.13 A doua parte a codului definit pentru butonul de adăugare a unui produs pe factură
Pentru ștergerea unui produs de pe lista produselor de pe factură , butonul Șterge va fi disponibil doar atunci când un produs este selectat (fig 3.3.14).
Fig 3.3.14 Ștergerea unui produs de pe lista produselor de pe factură
Implementarea butonului de facturare constă în crearea și inserarea în baza de date a unei facturi , pentru fiecare produs aflat pe lista facturii vom introduce în tabelul de legătură Facturi_Produse id-ul facturi și al produsului curent și cantitatea (fig 3.3.15).
Fig 3.3.15 Crearea facturi și inserarea facturi și a produseleor
Pentru fiecare produs stocul va fi modificat după acest pas, va deveni diferența dintre stocul actual minus cantitatea fiecarui produs .
Următorul pas va fi introducerea clientului și a angajatului corespunzator facturii (fig 3.3.16).
Fig 3.3.16 Inserarea clienților și a angajatului
Fereastra Facturi
Implementarea ferestrei pentru vizualizarea facturilor constă în definirea a două ListView-uri una pentru Facturi , iar ce a de a doua pentru vizualizarea în detaliu a produselelor de pe factură,două TextBox-uri în care se pot introduce date între care se poate face o sortare a facturilor, butoane pentru sortare , reîncărcarea tuturor facturilor și pentru întoarcerea la meniul principal.Acestea au fost definite în limbajul XAML (fig 3.3.17).
Fig 3.3.17 O parte din codul XAML al ferestrei facturi
Partea logică a ferestrei a fost implementată într-o clasă ViewModel setată ca și context de date.Încărcarea listei de facturi se face la deschiderea ferestrei punând metoda de încărcare (fig 3.3.18) în constructorul clasei ViewModel.
Fig 3.3.18 Încărcarea facturilor în listă
La fiecare schimbare a facturii selectate lista de produse va fi populată pentru factura curentă.Se va face o interogare corespunzătoare facturii selectate pentru a obține produsele vândute pe ea , rezultatul fiind transformat într-o listă și atribuit listei observabile Produse cea care este legată la ListView-ul de pe fereastră, corespunzător produselor (fig 3.3.19).
Fig 3.3.19 Popularea listei de produse
Butonul Sort ne permite să vizualizăm facturile dintr-o perioadă cuprinsă între două date (fig 3.3.20) ,de la o dată până la data curentă sau toate facturile emise până la o dată setată de noi.
Fig 3.3.20 Sortarea facturilor cuprinse între două date
Fereastra Conturi
Implementarea ferestrei pentru gestionarea conturilor constă în definirea unui ListView pentru vizualizarea conturilor , TextBox-uri pentru modificarea contului selectat și butoane de update și delete. Acestea au fost definite în limbajul XAML (fig 3.3.21).
Accesul la fereastra conturilor se face doar din fereastra angajaților a cărui acces este restricționat cu excepția angajaților din deparatamentul Gestiune.
Fig 3.3.21 O parte din codul XAML al ferestrei Conturi
Partea de implementare a fost realizată intr-o clasă ViewModel ,la încarcarea ferestrei vor fi încărcate conturile în ListView-ul folosit pentru conturi , iar butoanele Update și Delete au fost realizate în clase ce implementează interfața ICommnd.
3.4 Descrierea funcționalității aplicației
A fost realizată o aplicație pentru evidența activității unei firme de comerț ce permite reținerea , gestionarea și vizualizarea: produselor , angajaților , clienților , facturilor și a conturilor de acces.
Pentru accesul la aplicație este nevoie de autentificare.Fiecare angajat va avea un cont de acces la aplicație. Doar angajații din departamentul Gestiune vor avea acces la fereastra angajaților (fig 3.4.1).
Fig 3.4.1 Fereastra de logare
După autentificare se va deschide o nouă fereastră ce va conține meniul principal.În partea stângă de sus a ferestrei va fi numele contului pe care suntem logați și posibiliatatea de a ne deconecta de pe cont.
Fig 3.4.2 Meniul principal al aplicației
Meniul ne oferă posibilatatea de a accesa produsele , clienții ,angajații , facturile , fereastra de facturare sau ieșirea din aplicație fig(3.4.2).
Pentru a gestiona produsele vom accesa butonul Produse din meniul principal. Popularea listei cu produse se va face cu ajutorul combobox-ului ce conține categoriile de produse , iar în funcție de categoria selectată , lista de produse va fi umplută cu produsele ce fac parte din categoria respectivă.
Odată selectat un produs , se poate modifica numele , categoria, stocul sau prețul cu ajutorul câmpurilor de text .Id-ul unui produs nu poate fi modificat. Produsul poate fi șters daca acesta nu este prezent pe nici o factură.
Fig 3.4.3 Fereastra Produse
Pentru a adăuga un produs nou vom accesa butonul Adauga Produs ce ne va deschide o fereastră nouă.Aplicația oferă posibilitatea de a adăuga un produs nou într-o categorie existentă sau o categorie nouă (fig 3.4.4).
Fig 3.4.4 Adăugarea unui produs nou
Pentru a ne întoarce în meniul principal , din fereastra Produse vom utiliza butonul Inapoi.
Pentru a avea acces la fereastra angajați, contul pe care suntem logați trebuie să facă parte din departamentul Gestiune. La încărcarea ferestrei , vom aveam lista populată cu angajați asupra cărora se pot face modificări sau se pot șterge anumiți angajați (fig 3.4.5).
Fig 3.4.5 Fereastra Angajați
Putem adăuga angajați noi utilizând butonul Adauga Angajat.
Selectând un angajat îi putem crea un cont de autentificare utilizând butonul Adauga Cont ce ne va deschide o fereastră nouă (fig 3.4.6).
Fig 3.4.6 Fereastra Adaugă Cont
Putem șterge sau modifica un cont existent accesând butonul Cont ce ne va deschide o nouă fereastră cu lista conturilor (fig 3.4.7).
Fig 3.4.7 Fereastra conturi
Pentru a ne întoarce în meniul principal , din fereastra Angajați vom utiliza butonul Inapoi.
Gestionarea clienților se face accesând butonul Clienți din meniul principal.Aplicația permite adăugarea unui client folosind butonul Adauga Client din fereastra Clienti.Selectând un client din listă se pot modifica datele personale sau se poate șterge un client (fig. 3.4.8).
Fig 3.4.8 Fereastra Clienți
Accesând butonul Facturare din meniul principal, se va deschide o nouă fereastră unde putem înregistra o nouă factură.Pentru ca butonul Facturare din fereastra rezultată să fie activ , va trebui să selectăm un client din lista de clienți , să selectăm angajatul ce va emite facture , și să avem produse pe lista de produse a facturii.
Pentru a adăuga produse pe factură va trebui să încărcăm lista de produse cu ajutorul combobox-ului pentru categorie, să selectăm produsul și cantitatea pe care dorim să o adăugăm și să acționăm butonul Adaugă.Pentru a șterge un produs ce a fost adăugat va trebui selectat din lista de produse a facturii și acționat butonul Șterge.Prețul total va fi indicat într-un TextBox în partea dreapta jos a ferestrei (fig 3.4.9).
Fig 3.4.9 Fereastra Facturare
Un client poate fi adăugat din fereastra Clienți sau din fereastra de Facturare.Dacă va fi adăugat din fereastra de facturare va fi automat selectat pentru factura curentă.
Pentru a vizualiza facturile emise , din meniul principal se va accesa butonul Facturi ce ne va deschide o fereastră nouă.În fereastra Facturi vom avea încărcate toate facturile într-o listă , iar selectând o factură vom vedea într-o altă listă produsele ce au fost vândute pe acea factură. Aplicația ne permite să sortăm facturile după dată.Putem obține facturile a caror dată se află într-un interval.Este permisă și sortarea facturilor până la o dată anume sau de la o dată .Dacă dorim reîncărcarea facturilor vom acționa butonul Reincarca (fig 3.4.10).
Fig 3.4.10 Fereastra Facturi
Aplicația permite ștergerea unei facturi prin acționarea butonului Sterge Factura , având selectată factura pe care dorim să o ștergem.
Concluzii
Bibliografie
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: Aplicatie Informatica Pentru Evidentierea Activitatii Unei Firme de Comert (ID: 109932)
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.
