Отношение один-ко-многим (one-to-many) представляет ситуацию, когда одна сущность хранит ссылку на один объект другой сущности, а вторая сущность может ссылаться на коллекцию объектов первой сущности. Например, в одной компании может работать несколько сотрудников, а каждый сотрудник в свою очередь может официально работать только в одной компании:
using Microsoft.EntityFrameworkCore; public class Company { public int Id { get; set; } public string? Name { get; set; } public List<User> Users { get; set; } = new(); // сотрудники компании } public class User { public int Id { get; set; } public string? Name { get; set; } public int CompanyId { get; set; } public Company? Company { get; set; } // компания пользователя } public class ApplicationContext : DbContext { public DbSet<Company> Companies { get; set; } = null!; public DbSet<User> Users { get; set; } = null!; protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlite("Data Source=helloapp.db"); } }
Добавление данных:
using (ApplicationContext db = new ApplicationContext()) { // пересоздадим базу данных db.Database.EnsureDeleted(); db.Database.EnsureCreated(); // создание и добавление моделей Company microsoft = new Company { Name = "Microsoft" }; Company google = new Company { Name = "Google" }; db.Companies.AddRange(microsoft, google); User tom = new User { Name = "Tom", Company = microsoft }; User bob = new User { Name = "Bob", Company = microsoft }; User alice = new User { Name = "Alice", Company = google }; db.Users.AddRange(tom, bob, alice); db.SaveChanges(); }
Получение данных:
using (ApplicationContext db = new ApplicationContext()) { // вывод пользователей var users = db.Users.Include(u => u.Company).ToList(); foreach (User user in users) Console.WriteLine($"{user.Name} - {user.Company?.Name}"); // вывод компаний var companies = db.Companies.Include(c => c.Users).ToList(); foreach (Company comp in companies) { Console.WriteLine($"\n Компания: {comp.Name}"); foreach (User user in comp.Users) { Console.WriteLine($"{user.Name}"); } } }
Редактирование:
using (ApplicationContext db = new ApplicationContext()) { // изменение имени пользователя User? user1 = db.Users.FirstOrDefault(p => p.Name == "Tom"); if (user1!=null) { user1.Name = "Tomek"; db.SaveChanges(); } // изменение названия компании Company? comp = db.Companies.FirstOrDefault(p => p.Name == "Google"); if (comp != null) { comp.Name = "Alphabet"; db.SaveChanges(); } // смена компании сотрудника User? user2 = db.Users.FirstOrDefault(p => p.Name == "Bob"); if (user2 != null && comp!=null) { user2.Company = comp; db.SaveChanges(); } }
Удаление:
using (ApplicationContext db = new ApplicationContext()) { User? user = db.Users.FirstOrDefault(u => u.Name == "Bob"); if (user!=null) { db.Users.Remove(user); db.SaveChanges(); } Company? comp = db.Companies.FirstOrDefault(); if (comp != null) { db.Companies.Remove(comp); db.SaveChanges(); } }
Следует учитывать, что если зависимая сущность (в данном случае User) требует обязательного наличия главной сущности (в данном случае Company), то на уровне базы данных при удалении главной сущности с помощью каскадного удаления будут удалены и связанные с ней зависимые сущности. Так, в данном случае для объекта User установлено обязательное наличие объекта Company:
public int CompanyId { get; set; } public Company? Company { get; set; } // компания пользователя
Соответственно при удалении компании будут удалены и все связанные с ней пользователи.