Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Last active June 3, 2026 19:12
Show Gist options
  • Select an option

  • Save sunmeat/bf5a3bff2e48cab0d886f84c4b93e814 to your computer and use it in GitHub Desktop.

Select an option

Save sunmeat/bf5a3bff2e48cab0d886f84c4b93e814 to your computer and use it in GitHub Desktop.
code first: one-to-many example + migrations
// початкова версія: https://github.com/sunmeat/efcore_codefirst_ensurecreated
// ApplicationDbContext.cs:
using EFCoreCodeFirst.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
namespace EFCoreCodeFirst
{
// контекст бази даних
public class AppDbContext : DbContext
{
public DbSet<User>? Users => Set<User>();
public DbSet<Order>? Orders => Set<Order>();
public DbSet<Product>? Products => Set<Product>();
public DbSet<Category>? Categories => Set<Category>();
public AppDbContext()
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
optionsBuilder.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
}
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Models / Order.cs:
namespace EFCoreCodeFirst.Models
{
public class Order
{
public int Id { get; set; } // первинний ключ
public string ProductName { get; set; } = null!;
public decimal Price { get; set; }
public DateTime OrderDate { get; set; } = DateTime.UtcNow;
// зовнішній ключ + навігаційна властивість (зв'язок з User)
public int UserId { get; set; } // обов'язково!
public User User { get; set; } = null!; // навігаційна властивість (опціонально, але дуже зручно)
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Models / Category.cs:
namespace EFCoreCodeFirst.Models
{
public class Category
{
public int CategoryId { get; set; } // Primary Key
public string? Name { get; set; }
public ICollection<Product>? Products { get; set; } // 1 to many
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Models / Product.cs:
namespace EFCoreCodeFirst.Models
{
public class Product
{
public int ProductId { get; set; } // Primary Key
public string? Name { get; set; }
public decimal Price { get; set; }
public int CategoryId { get; set; } // Foreign Key
public Category? Category { get; set; } // navigation property
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Program.cs:
// без змін, додаткові методи - на ваш розсуд, про всяк випадок яка в мене була версія коду:
using EFCoreCodeFirst.Models;
using Microsoft.EntityFrameworkCore;
namespace EFCoreCodeFirst
{
class Program
{
private static readonly string[] Headers = { "ID", "Ім'я", "Вік", "Створено" };
static async Task Main()
{
Console.Title = "Code First";
Console.OutputEncoding = System.Text.Encoding.UTF8;
await using var db = new AppDbContext();
// !!! ці рядки вже не потрібні!
// await db.Database.EnsureDeletedAsync(); // видаляє БД, якщо вона існувала
// await db.Database.EnsureCreatedAsync(); // створює БД, якщо її не існує
Console.WriteLine("Перевірка та застосування міграцій...");
await db.Database.MigrateAsync();
Console.WriteLine("Міграції застосовані (або вже були актуальні).\n");
Console.WriteLine("Демонстрація роботи з EF Core:\n");
// додавання одного запису
await AddUserAsync(db, new User { Name = "Олександр", Age = 36 });
// додавання списку
await AddUsersAsync(db,
[
new User { Name = "Максим", Age = 24 },
new User { Name = "Ірина", Age = 22 },
new User { Name = "Софія", Age = 19 }
]);
// поточний стан
await PrintAllUsersAsync(db, "Початковий стан");
// оновлення
await UpdateUserAgeAsync(db, 1, 26);
await UpdateYoungUsersAgeAsync(db, 28);
await PrintAllUsersAsync(db, "Після оновлення");
// видалення
await DeleteUserAsync(db, 2);
await PrintAllUsersAsync(db, "Після видалення одного користувача");
// await DeleteAllUsersAsync(db);
// await PrintAllUsersAsync(db, "Після видалення всіх");
Console.WriteLine("\nНатисніть будь-яку клавішу для завершення...");
Console.ReadKey(true);
}
///////////////////////////////////////////////////////////////////
// методи роботи з даними (async)
private static async Task AddUserAsync(AppDbContext db, User user)
{
db.Users.Add(user);
await db.SaveChangesAsync();
Console.WriteLine($"Додано користувача: {user.Name} ({user.Age} років)");
}
private static async Task AddUsersAsync(AppDbContext db, User[] users)
{
db.Users.AddRange(users);
await db.SaveChangesAsync();
Console.WriteLine($"Додано {users.Length} користувачів");
}
private static async Task UpdateUserAgeAsync(AppDbContext db, int id, int newAge)
{
var user = await db.Users.FindAsync(id);
if (user is null)
{
Console.WriteLine($"Користувача з ID {id} не знайдено");
return;
}
user.Age = newAge;
await db.SaveChangesAsync();
Console.WriteLine($"Оновлено вік для {user.Name} → {newAge}");
}
private static async Task UpdateYoungUsersAgeAsync(AppDbContext db, int targetAge)
{
var youngUsers = await db.Users
.Where(u => u.Age < targetAge)
.ToListAsync();
if (youngUsers.Count == 0) return;
foreach (var user in youngUsers)
user.Age = targetAge;
await db.SaveChangesAsync();
Console.WriteLine($"Оновлено вік ({targetAge} років) для {youngUsers.Count} молодих користувачів");
}
private static async Task DeleteUserAsync(AppDbContext db, int id)
{
var user = await db.Users.FindAsync(id);
if (user is null) return;
db.Users.Remove(user);
await db.SaveChangesAsync();
Console.WriteLine($"Видалено користувача: {user.Name}");
}
private static async Task DeleteAllUsersAsync(AppDbContext db)
{
var count = await db.Users.CountAsync();
if (count == 0) return;
db.Users.RemoveRange(db.Users);
await db.SaveChangesAsync();
Console.WriteLine($"Видалено всіх користувачів ({count})");
}
private static async Task PrintAllUsersAsync(AppDbContext db, string title)
{
var users = await db.Users
.OrderBy(u => u.Id)
.ToListAsync();
Console.WriteLine($"\n{title}");
Console.WriteLine(new string('-', 60));
if (users.Count == 0)
{
Console.WriteLine("Таблиця порожня");
return;
}
// красиве виведення таблицею
Console.WriteLine($"{Headers[0],-4} | {Headers[1],-15} | {Headers[2],-5} | {Headers[3]}");
Console.WriteLine(new string('-', 60));
foreach (var u in users)
{
Console.WriteLine($"{u.Id,-4} | {u.Name,-15} | {u.Age,-5} | {u.CreatedAt:yyyy-MM-dd HH:mm}");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment