Чи є місце запитам до бази в бізнес-логіці .NET-застосунку?
🧣 ЧИ Є МІСЦЕ ЗАПИТАМ ДО БАЗИ В БІЗНЕС-ЛОГІЦІ .NET-ЗАСТОСУНКУ?
Поки ти просто пишеш CRUD — все виглядає «зручно»:
var users = _db.Users.Where(u => u.IsActive).Include(u => u.Roles).ToListAsync();
Але варто лише спробувати покрити це юніт-тестом — і відразу видно, наскільки це погана ідея:
ToListAsync()
не мокнеться- треба тягнути EF InMemory або сторонні бібліотеки типу
MockQueryable.Moq
- весь сервіс змішує бізнес-логіку з SQL-подібною LINQ-кашею
А потім ще хтось каже:
«У нас не DbContext напряму — у нас GenericRepository, який повертає IQueryable»
😅 Та це ж усе та сама штука. Просто обгортка над DbSet
, яка нічого не інкапсулює.
Запит як був у бізнес-логіці — так і залишився.
❓ А ЧИ МОЖНА ВВАЖАТИ ЦЕ «РЕПОЗИТОРІЄМ»?
Якщо обʼєкт просто повертає IQueryable
— це не репозиторій.
СУХЕ ПОРІВНЯННЯ:
1. Читабельність
✅ Метод у сервісі виглядає як бізнес-дія — GetActiveUsers()
❌ .Where(...), .Include(...)
, .OrderBy(...)
прямо у методі
2. Відокремлення шарів
✅ Сервіс читає дані через API (IUserRepository.GetActiveUsers()
)
❌ Сервіс будує запит сам через IQueryable
3. Тестування
✅ Легко мокати методи, просте тестування
❌ Потрібно мокати IQueryable
, ToListAsync()
— складно, часто нестабільно
4. Розподіл обов’язків
✅ Репозиторій відповідає за доступ до даних
❌ Сервіс одночасно вирішує і що зробити, і як отримати дані
5. Контроль над запитом
✅ Централізовано: Include
, Where
, OrderBy
— в одному місці
❌ Логіка розмазана по різних методах, важко відстежити зміни
6. Типові виправдання
🟢 «У нас не DbContext напряму, а GenericRepository»
🔴 Але це та ж суть — ті самі проблеми, інша упаковка
📌 Приклад для порівняння
Погано:
var users = _repository.GetAll() .Where(u => u.IsActive && !u.IsDeleted) .Include(u => u.Roles) .OrderBy(u => u.CreatedAt);
Добре:
var users = await _userRepository.GetActiveUsersSorted();
🗣 ЯК ВИ ЦЕ РОБИТЕ У СЕБЕ?
- Використовуєте повноцінні репозиторії?
- Чи прокидаєте
IQueryable
в бізнес-логіку? - Чи вважаєте це окейним підходом?
👇 Діліться досвідом в коментарях!
25 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів