Sobes.tech
Middle

Jak zaimplementować relację 'jeden do wielu' w bazie danych lub w kodzie C#?

sobes.tech AI

Odpowiedź od AI

W bazie danych:

  • Tworzone są tabele dla "jednego" (rodzica) i "wielu" (dzieci).
  • Do tabeli "wielu" dodawany jest klucz obcy odwołujący się do klucza głównego tabeli "jednego".
  • Przykład: Tabele Companies i Employees. W tabeli Employees znajduje się kolumna CompanyId (klucz obcy), odwołująca się do Id (klucz główny) w tabeli Companies.

W kodzie C#:

Z użyciem Entity Framework Core:

  • Definiowane są klasy modeli dla rodzica i dzieci.
  • Klasa rodzica zawiera kolekcję obiektów dzieci.
  • Klasa dziecka zawiera odwołanie do obiektu rodzica i klucz obcy.
    public class Company
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public ICollection<Employee> Employees { get; set; } // Właściwość nawigacyjna dla "wielu"
    }
    
    public class Employee
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int CompanyId { get; set; } // Klucz obcy
        public Company Company { get; set; } // Właściwość nawigacyjna dla "jednego"
    }
    
  • W kontekście bazy danych konfiguruje się relacje (czasami Entity Framework Core może je wykryć na podstawie konwencji).
    public class ApplicationDbContext : DbContext
    {
        public DbSet<Company> Companies { get; set; }
        public DbSet<Employee> Employees { get; set; }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // Wyraźne określenie relacji (nie zawsze konieczne)
            modelBuilder.Entity<Company>()
                .HasMany(c => c.Employees) // Firma ma wielu pracowników
                .WithOne(e => e.Company) // Pracownik ma jedną firmę
                .HasForeignKey(e => e.CompanyId); // Klucz obcy w tabeli Employee
        }
    }
    

Bez ORM (ręcznie):

  • Pobieranie danych z bazy danych za pomocą zapytań JOIN.
    // Przykład zapytania SQL
    // SELECT c.Name AS CompanyName, e.Name AS EmployeeName
    // FROM Companies c
    // JOIN Employees e ON c.Id = e.CompanyId;
    
  • Tworzenie odpowiednich klas i ręczne łączenie obiektów po pobraniu danych.
    public class Company
    {
        public string Name { get; set; }
        public List<Employee> Employees { get; set; } // Kolekcja do przechowywania powiązanych obiektów
    }
    
    public class Employee
    {
        public string Name { get; set; }
    }
    
    // Przykład tworzenia obiektów po pobraniu danych
    // Company company = new Company { Name = "ACME Corp", Employees = new List<Employee>() };
    // company.Employees.Add(new Employee { Name = "Alice" });
    // company.Employees.Add(new Employee { Name = "Bob" });