C#: relații și chei în DataTable și DataSet
Modelează două tabele corelate în C# și verifică integritatea datelor. Folosește chei primare și DataRelation pentru a împiedica referințele inexistente.
În acest material
O carte și un împrumut sunt entități diferite. Dacă repetăm titlul cărții în fiecare împrumut, o corectare a titlului trebuie făcută în multe locuri. Păstrăm cartea într-un tabel și referim BookId din împrumuturi. Relația spune că fiecare împrumut trebuie să indice o carte existentă.
Cum lucrezi cu exemplul
Programul complet folosește C# 7.3 și API-uri disponibile în .NET Framework 4.8. Deschide Lesson.csproj din arhivă sau creează un proiect Console App (.NET Framework 4.8) și înlocuiește Program.cs. Datele de demonstrație sunt incluse în cod.
Descarcă sursele și instrucțiunile.
Ideea și pașii de implementare
DataTable definește coloane cu tipuri, iar PrimaryKey identifică unic rândul. DataSet grupează tabelele și relațiile. DataRelation creată cu constrângeri verifică integritatea referințelor în memorie. Această verificare nu înlocuiește cheile din baza de date reală, dar permite înțelegerea regulii înainte de configurarea providerului.
Adăugăm întâi tabela părinte, apoi tabela copil. O relație folosește coloane compatibile ca tip. Un nume de coloană identic nu creează singur o legătură; trebuie definită relația și păstrate constrângerile active.
Exemplu și rezultat așteptat
Books conține ID 1. Împrumutul 10 referă cartea 1 și este acceptat. Împrumutul 11 referă cartea 99 și este respins. Numărul împrumuturilor rămâne unu. Programul afișează Refuz: carte inexistenta și Imprumuturi: 1.
Books: BookId 1 → Loans: 10 → BookId 1 → Loans: 11 → BookId 99 → 99 lipsește → refuz.Mărește schema ↗
Codul complet
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Globalization;
using System.Xml.Linq;
using System.Data;
class Program {
static void Main() {
var data=new DataSet();var books=new DataTable("Books");var loans=new DataTable("Loans");
books.Columns.Add("BookId",typeof(int));books.Columns.Add("Title",typeof(string));
books.PrimaryKey=new[] {books.Columns["BookId"]};
loans.Columns.Add("LoanId",typeof(int));loans.Columns.Add("BookId",typeof(int));
loans.PrimaryKey=new[] {loans.Columns["LoanId"]};
data.Tables.Add(books);data.Tables.Add(loans);
data.Relations.Add("BookLoans",books.Columns["BookId"],loans.Columns["BookId"],true);
books.Rows.Add(1,"Algoritmi");loans.Rows.Add(10,1);
try {loans.Rows.Add(11,99);} catch(InvalidConstraintException) {Console.WriteLine("Refuz: carte inexistenta");}
Console.WriteLine("Imprumuturi: " + loans.Rows.Count);
}
}
Rezultatul programului:
Refuz: carte inexistenta
Imprumuturi: 1
Greșeli și limite
Nu dezactiva permanent constrângerile ca să „meargă importul”. Dacă le dezactivezi temporar într-un scenariu controlat, trebuie să le reactivezi și să tratezi erorile înainte de folosirea datelor. Nu elimina automat părintele și toate datele copil fără să decizi politica domeniului.
Exersează
Încearcă două cărți cu același ID și verifică refuzul. Adaugă cartea 99, apoi împrumutul care o referă: acum trebuie acceptat. Desenează relația unu-la-mulți și explică de ce două împrumuturi pot avea același BookId, dar nu același LoanId.
Continuă parcursul
Parcursul complet de 50 de lecții
Lecția precedentă: C#: miniaplicație cu grilă și stare separată de butoane
Lecția următoare: C#: proiectează schema SQL înaintea formularelor.
Referință: documentația Microsoft.
Întrebări frecvente
Ce diferență au cheia primară și cheia externă?
Prima identifică unic rândul, a doua leagă rândul de o entitate existentă în alt tabel.
DataSet este o bază de date persistentă?
Nu. Este o structură în memorie; salvarea se implementează separat.
Pot avea mai multe împrumuturi pentru o carte?
Da. Relația permite mai mulți copii pentru același părinte, cu ID-uri proprii distincte.
Un pas mai departe
Autentifică-te pentru a păstra progresul în cont.