Sustin tot ce a spus andrei in ultimul sau post, dar as propune o a doua varianta, care, dupa parerea mea, s-ar putea sa ti se para mai simpla putin si mai straight-forward : sa folosesti LinqToSql. Dezavantajul acestei metode, in cazul tau, ar fi ca sari peste partea de invatat query-uri sql, conceptul de procedura stocata etc.
1) Cauta documentatie LinqToSql (MSDN,
CodeProject,
C# Corner ).
2) Am sa iti descriu, pe scurt :
(Later edit: nu am fost atent cand am scris post-ul, tabelul prezentat de tine mai sus se numeste Societati Comerciale. Eu am folosit in cadrul postului Clients)
Linq face mapare intre obiectele date (data types) si tabele din baza de date.
(Observatie: in printscreen-ul de mai sus, am vazut ca nu ai un camp Id, care, in mod uzual, este utilizat pentru a identifica in mod unic un record (cheie primara). In cazul tabelei Clienti, ai putea folosi CUI-ul ca si id, ca primary key, desi recomand sa mai pui un camp IdClient, pe care sa il setezi de tip identity => db-ul va genera in id unic, incepand de la 0, pe care il va incrementa cu fiecare record adaugat; astfel, nu trebuie sa iti ma bati capul cu generarea unui id nou de fiecare data cand vrei sa inserezi ceva.)
Pas 1: creezi tabelele, definesti cheia primara.
ex : tabelul Clients de mai sus
Pas 2: in cod, ai clasa Clients.cs, care modeleaza conceptul de Client.
Pentru a face maparile, clasa ta va arata asemanator:
Code: Select all
[Table(Name="dbo.Clients")]
public class Client
{
// IsPrimaryKey e evident ce face; IsDbGenerated ii spune framework-ului ca aceasta proprietate, IdClient, se va mapa pe un record camp declarat Identity in DB.
[Column(IsPrimaryKey = true, IsDbGenerated = true)]
public int IdClient { get; set; }
[Column]
public string Societate { get; set; }
[Column]
public string CUI { get; set; }
// alte proprietati ale clasei
}
Pas 3: Creezi un DataContext pentru fiecare mapare Clasa-Tabel_DB. DataContext-ul reprezinta un wrapper, cu ajutorul caruia efectuezi diverse operatii cu baza de date. Documenteaza-te putin pe net.
Code: Select all
public class ClientsDataContext : DataContext
{
public ClientsDataContext(string connectionString) : base(connectionString) { }
}
Pas 4: Clasa din layer-ul DataAccess, care opereaza asupra bazei de date:
In aceasta clasa, sunt declarate atat DataContext-ul, cat si un obiect de tipul Table, care este un "holder" pentru datele tale => poti implementa astfel un fel de mecanism de cache, sa nu faci n call-uri la baza de date (not healthy).
Code: Select all
public class ClientsDAL
{
private ClientsDataContext _clientsDataContext = null;
private Table<Client> _clientsTable = null;
private ClientsDataContext ClientsContext
{
if(_clientsDataContext == null)
_clientsDataContext = new ClientsDataContext(connectionString);
return _clientsDataContext;
}
private Table<Client> ClientsTable
{
if(_clientsTable == null)
_clientsTable = ClientsContext.GetTable<Client>();
return _clientsTable;
}
//metode de tipul get:
public Client GetClient(int idClient)
{
IQueryable<Client> query = ClientsTable.Where<Client>(client => client.IdClient == idClient);
if(query.Count() > 0)
return query.First<Client>();
return null;
}
public Client GetClient(string cui)
{
IQueryable<Client> query = ClientsTable.Where<Client>(client => client.CUI.ToLower() == cui.ToLower());
if(query.Count() > 0)
return query.First<Client>();
return null;
}
public List<Client> GetClients()
{
if(ClientsTable.ToList<Client>().Count > 0)
return ClientsTable.ToList<Client>();
return null;
}
//metode de insert
public Boolean SaveClient(Client client)
{
if(client != null)
{
ClientsTable.InsertOnSubmit(client);
try
{
ClientsContext.SubmitChanges();
return true;
}
catch(Exception ex)
{
return false;
}
}
}
//update
public Boolean UpdateClient(Client client)
{
//trebuie sa cauti, dupa id, clientul care e in baza de date, sa il actualizezi
var query = from c in ClientsTable
where c.IdClient == client.IdClient
select c;
if(query.Count() == 0)
return false; // daca ajungi aici, inseamna ca nu s-a gasit clientul cu id-ul dat ca param. sau te intorci cu false si afisezi un mesaj sau apelezi metoda de insert => return this.SaveClient(client);
Client oldClient = query.First<Client>();
oldClient.CUI = client.CUI;
oldClient.Societate = client.Societate;
// .....
try
{
ClientsContext.SubmitChanges();
return true;
}
catch(Exception ex)
{
return false;
}
}
}
In metoda de Insert, obiectul Client va fi adaugat doar in Table (care e un obiect al .net-ului), nu direct in DB. Pentru a face commit-ul in DB, se apeleaza metoda SubmitChanges() din DataContext (blocul try-catch). Pentru a evita si mai mult acele call-uri la baza de date, de care spunea mai sus, ai putea scoate acel bloc try-catch din metodele de insert, delete pe care le vei avea, si sa il pui intr-o metoda, pe care sa o denumesti ceva de genul SubmitChangesToDb, CommitToDb, pe care sa o apelezi o singura data, dupa ce ai terminat de adaugat toti clientii. Doar atunci, continului ClientsTable se va sincroniza cu tabelul Clients din baza de date.
In cazul metodelor de update, oldClient nu este o copie a record-ului din ClientsTable, ci chiar o referinta spre record-ul respectiv. Deci orice modificare asupra proprietatilor Client-ului, se vor face direct in Table. La SubmitChanges() acestea vor fi introduse in DB.
Am incercat sa expun in code snippet-urile de mai sus modul de a folosi Linq pentru operatiile de I/O cu Db-ul. Sper ca am fost destul de clar, si te vei prinde repede. Nu e greu, dupa ce ai putin exercitiu, o sa zboare chestiile astea.
Acum, in UI vad ca ai folosit binding navigator-ul. Nu am mai folosit WindowsForms de ceva vreme, dar din cat mai tin minte, acel navigator ofera o proprietate DataSource. Ei bine, la acel DataSource, poti trimite o lista de clienti. Fiecare camp din acel navigator ar trebui sa aiba ceva de genul Target, in sectiunea Proprieties a UI-ului IDE-ului (disclaimer: nu mai tin minte cum se face, nu am folosit demult) In acest caz, setezi fiecarui camp la target proprietatea obiectului Client care doresti sa fie afisata.
ceva in genul, presupunand ca ai o instanta a ClientDAL-ului :
Code: Select all
List<Client> clients = clientDAL.GetClients();
if(clients != null)
{
bindingNavigatorClients.DataSource = clients;
bindingNavigatorClients.BindData();
}
Sper ca am reusit sa te ajut, sa iti ofer o alternativa la ceea ce ti-a sugerat andrei. Alegerea este a ta.
Avantajele metodei lui andrei : vei invata SQL, query-uri, proceduri stocate, constangeri etc;
Avantajele metodei sugerate de mine : mai rapida ( atat ca timp de development, cat si ca timp de executie <aici s-ar putea sa fie ceva discutii, cum ca procedurile stocare ar fi mai rapide, sau metoda in general ar fi mai rapida; depinde de multi factori, pentru ceea ce ai nevoie de tu, e foarte ok), mai simpla dupa ce te prinzi de procedeu, mai clara.
Disclaimer 1 : Acesta este primul meu post in sectiunea de programare, in care ofer un sfat / exemplu / sugestie. Asadar, sunt deschid la critici.
Disclaimer 2 : Post-ul presupune ca ai concepte de OOP; am presupus ca ai si conceptul de arhitectura n-tier a unei aplicatii (UI, BusinessLayer, DataAccessLayer, DataTypesLayer);
Disclaimer 3 : Varianta prezentata mai sus este doar un schelet, pentru exemplificare; nu e varianta cea mai optima de scriere a unui cod.
Disclaimer 4 : In viitoarele editari ale postului
