Как находить медленные запросы в Entity Framework
Используя систему перехватчиков Entity Framework и подключаясь к событию
Сохрани в закладки🧀
Как это работает
1. Создаём класс перехватчика, наследуемся от
2. Регистрируем этот перехватчик в контексте через
👉 @KodBlog
Используя систему перехватчиков Entity Framework и подключаясь к событию
ReaderExecuted мы можем видеть сколько времени реально занимают запросыСохрани в закладки
public class SlowQueryInterceptor : DbCommandInterceptor
{
private const int _slowQueryThreshold = 200; // миллисекунды
public override DbDataReader ReaderExecuted(
DbCommand command,
CommandExecutedEventData eventData,
DbDataReader result)
{
if (eventData.Duration.TotalMilliseconds > _slowQueryThreshold)
{
// Логируем медленный запрос — тут можно вставить свою систему логирования
Console.WriteLine(
$"Slow query ({eventData.Duration.TotalMilliseconds} ms): {command.CommandText}");
}
return base.ReaderExecuted(command, eventData, result);
}
}
public class YourDbContext : DbContext
{
// ... твои DbSet ...
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer("YourConnectionString") // замени на свою строку подключения
.AddInterceptors(new SlowQueryInterceptor());
}
}
Как это работает
1. Создаём класс перехватчика, наследуемся от
DbCommandInterceptor и реализуем метод ReaderExecuted2. Регистрируем этот перехватчик в контексте через
AddInterceptorsPlease open Telegram to view this post
VIEW IN TELEGRAM
👍20❤3🔥1
Изоляция данных в модульном монолите
- Схема и роль на модуль — для каждого модуля создаётся собственная схема и роль
- Привилегии только для своей схемы — модуль не имеет доступа к данным других схем
- Отдельный DbContext + схема по умолчанию — разделение кода и данных на уровне ORM
- Разные строки подключения и миграции — независимое управление конфигурацией и развёртыванием
- Read-only представления для межмодульных запросов — безопасный доступ к данным между модулями
Смотрите пошаговое руководство: ссылка
👉 @KodBlog
- Схема и роль на модуль — для каждого модуля создаётся собственная схема и роль
- Привилегии только для своей схемы — модуль не имеет доступа к данным других схем
- Отдельный DbContext + схема по умолчанию — разделение кода и данных на уровне ORM
- Разные строки подключения и миграции — независимое управление конфигурацией и развёртыванием
- Read-only представления для межмодульных запросов — безопасный доступ к данным между модулями
Смотрите пошаговое руководство: ссылка
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5🔥1👏1
Сохрани этот пост
Покажу репозиторий на GitHub, где есть 99% кода, который тебе нужен для разработки
485 примеров кода .NET в одном месте🙏
Репозиторий называется:
practical-aspnetcore — https://github.com/dodyg/practical-aspnetcore
В одном месте собрано 485 практических примеров, чтобы ты мог понять и эффективно внедрить ключевые возможности ASP .NET Core
Что покрыто:
Это, по сути, швейцарский нож для .NET - инструменты почти для любой ситуации
👉 @KodBlog
Покажу репозиторий на GitHub, где есть 99% кода, который тебе нужен для разработки
485 примеров кода .NET в одном месте
Репозиторий называется:
practical-aspnetcore — https://github.com/dodyg/practical-aspnetcore
В одном месте собрано 485 практических примеров, чтобы ты мог понять и эффективно внедрить ключевые возможности ASP .NET Core
Что покрыто:
Authentication
Blazor
Caching
gRPC
HealthCheck
Localization
Logging
Middleware
Minimal API
Open Telemetry
Routing
SignalR
Security
YARP
Это, по сути, швейцарский нож для .NET - инструменты почти для любой ситуации
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20❤5🔥5😁1
Что такое RBAC и как это помогает с авторизацией
RBAC расшифровывается как Role-Based Access Control, то есть управление доступом на основе ролей
Суть простая
• У ролей есть набор разрешений
• Пользователи получают роли
• Разрешения определяют, что пользователи могут делать
Всё довольно просто, но при этом мощно
Хотя сами по себе роли могут быть слишком широкими
Поэтому я предпочитаю комбинировать роли с более точечными разрешениями.
Вместо того чтобы хардкодить правила доступа, я привязываю разрешения к конкретным действиям и уже потом связываю эти разрешения с ролями
Так проще управлять и легче расширять
Как смоделировать такой подход и применить его в .NET — читать
А как у тебя сейчас устроена авторизация в системе😏
👉 @KodBlog
RBAC расшифровывается как Role-Based Access Control, то есть управление доступом на основе ролей
Суть простая
• У ролей есть набор разрешений
• Пользователи получают роли
• Разрешения определяют, что пользователи могут делать
Всё довольно просто, но при этом мощно
Хотя сами по себе роли могут быть слишком широкими
Поэтому я предпочитаю комбинировать роли с более точечными разрешениями.
Вместо того чтобы хардкодить правила доступа, я привязываю разрешения к конкретным действиям и уже потом связываю эти разрешения с ролями
Так проще управлять и легче расширять
Как смоделировать такой подход и применить его в .NET — читать
А как у тебя сейчас устроена авторизация в системе
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥4👍3❤2🔥2
Я отучаюсь от всего, что знал про юнит-тестирование
Потому что большая часть этого — неправда
Для юнит-тестов нужен mocking-фреймворк
Юнит-тест должен покрывать один метод
С EF Core обязательно использовать Repository-паттерн для тестирования
Если всё это совместить, получаются хрупкие тесты, которые ничего не говорят о требованиях и вынуждают плодить ненужные слои
Вместо этого я придерживаюсь простых правил
• Использовать фейки вместо mocking-фреймворка
• Юнит-тесты проверяют поведение, а не структуру
• При работе с EF Core использовать in-memory или SQLite провайдер и обходить их ограничения через интеграционные тесты
Так тесты становятся менее хрупкими, покрывают больше кода и требуют меньше поддержки
Кто со мной?
👉 @KodBlog
Потому что большая часть этого — неправда
Для юнит-тестов нужен mocking-фреймворк
Юнит-тест должен покрывать один метод
С EF Core обязательно использовать Repository-паттерн для тестирования
Если всё это совместить, получаются хрупкие тесты, которые ничего не говорят о требованиях и вынуждают плодить ненужные слои
Вместо этого я придерживаюсь простых правил
• Использовать фейки вместо mocking-фреймворка
• Юнит-тесты проверяют поведение, а не структуру
• При работе с EF Core использовать in-memory или SQLite провайдер и обходить их ограничения через интеграционные тесты
Так тесты становятся менее хрупкими, покрывают больше кода и требуют меньше поддержки
Кто со мной?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤4🤔2😁1
Предпочитай
1. Корректность (например, проблема с турецкой буквой
2. Читаемость
3. Производительность
👉 @KodBlog
string.Equals вместо ToLower / ToUpper для нечувствительных к регистру сравнений строк1. Корректность (например, проблема с турецкой буквой
i)2. Читаемость
3. Производительность
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤4🔥2👏1
Нужны пиксельно идеальные PDF-отчёты в .NET?
Забей на проприетарные библиотеки, используй HTML-шаблоны и PuppeteerSharp.
Собери отчёт как HTML-шаблон на Handlebars, подставь данные, а потом отрендерь в PDF через headless-браузер.
Учись генерировать удобные и красивые PDF-отчёты с
👉 @KodBlog
Забей на проприетарные библиотеки, используй HTML-шаблоны и PuppeteerSharp.
Собери отчёт как HTML-шаблон на Handlebars, подставь данные, а потом отрендерь в PDF через headless-браузер.
Учись генерировать удобные и красивые PDF-отчёты с
Handlebars.NET и PuppeteerSharp — гайд МиланаPlease open Telegram to view this post
VIEW IN TELEGRAM
❤12👍4
Вызов Azure Function из Azure SQL DB
Да, это реально. Хранимая процедура
Кто-то уже пробовал?
👉 @KodBlog
Да, это реально. Хранимая процедура
sp_invoke_external_rest_endpoint позволяет дергать HTTPS REST endpoint, переданный ей в качестве аргумента.Кто-то уже пробовал?
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍2🤔2🎉2🔥1
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🤔4🍌2🤨2
Лучшая техника dependency injection, которой почти никто не пользуется
(больше никаких конструкторов на 10 строк)
Используй
Это малоизвестная фича в ASP.NET Core, которая позволяет инжектить зависимости прямо в метод эндпоинта
Для этого можно использовать
Но
Когда это уместно
• Когда сервис нужен только в одном экшене
• Когда конструктор превращается в лапшу
• Когда сервис тяжёлый и хочется лучше контролировать память
Да, constructor injection по умолчанию — это стандартный подход
Но method injection — это удобный инструмент, если хочется делать более мелкие сервисы, которые соблюдают принцип единственной ответственности, и при этом иметь контроллеры, не превращённые в свалку зависимостей
👉 @KodBlog
(больше никаких конструкторов на 10 строк)
Используй
Method InjectionЭто малоизвестная фича в ASP.NET Core, которая позволяет инжектить зависимости прямо в метод эндпоинта
Для этого можно использовать
[FromServices] IYourServiceНо
[FromServices] можно и не указыватьКогда это уместно
• Когда сервис нужен только в одном экшене
• Когда конструктор превращается в лапшу
• Когда сервис тяжёлый и хочется лучше контролировать память
Да, constructor injection по умолчанию — это стандартный подход
Но method injection — это удобный инструмент, если хочется делать более мелкие сервисы, которые соблюдают принцип единственной ответственности, и при этом иметь контроллеры, не превращённые в свалку зависимостей
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤🔥4❤2😁2🔥1
Твой опыт с NuGet в .NET ограничивается AutoMapper?
Быть в курсе .NET = быть в курсе инструментов.
Не отставай — вот 24 NuGet-библиотеки
👉 @KodBlog
Быть в курсе .NET = быть в курсе инструментов.
Не отставай — вот 24 NuGet-библиотеки
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🔥1
Когда исключения неизбежны, нужен механизм для их обработки.
Вот как это можно настроить за несколько минут:
Начиная с .NET 8 у вас есть интерфейс
Это абстракция для управления исключениями с одним методом:
Он отвечает за обработку исключений в пайплайне ASP.NET Core.
Метод возвращает
Это позволяет реализовать кастомную логику под разные сценарии.
Для конфигурации нужно сделать три шага:
1. Зарегистрировать сервис
2. Зарегистрировать
3. Зарегистрировать
Третий шаг опционален, но я настоятельно рекомендую его использовать, чтобы ошибки были более читаемыми.
👉 @KodBlog
Вот как это можно настроить за несколько минут:
Начиная с .NET 8 у вас есть интерфейс
IExceptionHandlerЭто абстракция для управления исключениями с одним методом:
TryHandleAsyncОн отвечает за обработку исключений в пайплайне ASP.NET Core.
Метод возвращает
true, если исключение обработано успешно, и false, если его нельзя обработать.Это позволяет реализовать кастомную логику под разные сценарии.
Для конфигурации нужно сделать три шага:
1. Зарегистрировать сервис
IExceptionHandler через dependency injection2. Зарегистрировать
ExceptionHandlerMiddleware в пайплайне запросов3. Зарегистрировать
ProblemDetails ответТретий шаг опционален, но я настоятельно рекомендую его использовать, чтобы ошибки были более читаемыми.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤5
Хочешь писать более чистый C#-код?
Начни с чистых функций.
Чистая функция проста:
Берёт входные данные, возвращает результат и больше ни на что не влияет.
Никаких запросов в базу. Никаких случайных значений. Никаких скрытых побочных эффектов
Такой код легче тестировать, отлаживать и ему проще доверять.
Если логика кажется непредсказуемой — попробуй вынести её в чистую функцию.
Удивишься, насколько всё станет понятнее.
👉 @KodBlog
Начни с чистых функций.
Чистая функция проста:
Берёт входные данные, возвращает результат и больше ни на что не влияет.
Никаких запросов в базу. Никаких случайных значений. Никаких скрытых побочных эффектов
Такой код легче тестировать, отлаживать и ему проще доверять.
Если логика кажется непредсказуемой — попробуй вынести её в чистую функцию.
Удивишься, насколько всё станет понятнее.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤2🤨2
Примеры использования разделителя цифр (_) в C#
👉 @KodBlog
// Можно использовать в целых числах
int oneMillion = 1_000_000;
Console.WriteLine(oneMillion); // Выведет: 1000000
// Работает и с числами с плавающей точкой
double billion = 1_000_000_000.0;
Console.WriteLine(billion); // Выведет: 1000000000
// Поддерживается и в двоичной, и в шестнадцатеричной записи
int binary = 0b1010_1011_1100;
Console.WriteLine(binary); // Выведет: 2748
int hexadecimal = 0x1234_abcd;
Console.WriteLine(hexadecimal); // Выведет: 305441741
Please open Telegram to view this post
VIEW IN TELEGRAM
👍29🔥6❤4
До сих пор выкатываешь новые фичи через
Есть решение получше.
В .NET есть отличная поддержка feature flags, и что важнее - таргетированных feature flags
Это значит, что можно включать функциональность:
- только для внутренних тестировщиков
- для определённого сегмента пользователей
- или даже для одного конкретного юзера
Больше никаких флагов "для всех сразу". Больше никаких костылей с разветвлённой логикой в коде.
Ты задаёшь правила, а .NET сам обрабатывает таргетинг.
А если совместить это с версионированием API, то получаешь полный контроль над тем, кто и когда увидит новое поведение.
Feature flags — это не просто переключатель кода. Это инструмент доставки продукта.
👉 @KodBlog
if?Есть решение получше.
В .NET есть отличная поддержка feature flags, и что важнее - таргетированных feature flags
Это значит, что можно включать функциональность:
- только для внутренних тестировщиков
- для определённого сегмента пользователей
- или даже для одного конкретного юзера
Больше никаких флагов "для всех сразу". Больше никаких костылей с разветвлённой логикой в коде.
Ты задаёшь правила, а .NET сам обрабатывает таргетинг.
А если совместить это с версионированием API, то получаешь полный контроль над тем, кто и когда увидит новое поведение.
Feature flags — это не просто переключатель кода. Это инструмент доставки продукта.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21❤3🔥2❤🔥1
dotnet-backend-blueprint.zip
63.6 KB
Устал каждый раз собирать .NET-проекты с нуля?
Есть готовый blueprint для .NET backend, в котором уже настроены 12 продакшен-фич:
- Современный .NET 9 Web API
- Архитектура Vertical Slice
- PostgreSQL + Entity Framework Core
- Преднастроенная аутентификация через Keycloak
- Swagger UI с поддержкой авторизации для интерактивного тестирования
- Глобальная обработка ошибок
- Локальная разработка с .NET Aspire без лишних танцев
- Интеграционные тесты на Test Containers
- Деплой на Azure в продакшн
- CI/CD пайплайны для GitHub Actions и Azure DevOps
- Поддержка GitHub Codespaces
- Шаблон dotnet new готов к установке
Это не очередной "Hello World". Это полноценный продакшен-бэкенд, который обычно занимает у разработчиков недели настройки.
Собран на Vertical Slice Architecture, потому что чистый код важнее, чем следование устаревшим слоёным паттернам.
Честно, если делаешь простые CRUD-приложения, это перебор. Но если нужен API, готовый к продакшену без мучений на старте этот шаблон сэкономит тебе 40+ часов.
👉 @KodBlog
Есть готовый blueprint для .NET backend, в котором уже настроены 12 продакшен-фич:
- Современный .NET 9 Web API
- Архитектура Vertical Slice
- PostgreSQL + Entity Framework Core
- Преднастроенная аутентификация через Keycloak
- Swagger UI с поддержкой авторизации для интерактивного тестирования
- Глобальная обработка ошибок
- Локальная разработка с .NET Aspire без лишних танцев
- Интеграционные тесты на Test Containers
- Деплой на Azure в продакшн
- CI/CD пайплайны для GitHub Actions и Azure DevOps
- Поддержка GitHub Codespaces
- Шаблон dotnet new готов к установке
Это не очередной "Hello World". Это полноценный продакшен-бэкенд, который обычно занимает у разработчиков недели настройки.
Собран на Vertical Slice Architecture, потому что чистый код важнее, чем следование устаревшим слоёным паттернам.
Честно, если делаешь простые CRUD-приложения, это перебор. Но если нужен API, готовый к продакшену без мучений на старте этот шаблон сэкономит тебе 40+ часов.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍6🔥2👏1
Разница между
🔸
- Пишется проще
- Загружает все совпавшие ID в память
- Тормозит на больших таблицах (например, Customers)
- Может плохо работать без индексов
- В случае
🔸
- Останавливается на первом совпадении
- Лучше дружит с индексами
- Эффективнее при коррелированных подзапросах
- Корректно обходит
- По производительности
- На маленьких выборках: разница минимальна
- На больших: чаще выигрывает
- В коррелированных подзапросах: почти всегда лучше
Современные оптимизаторы умеют уравнивать разницу, но понимать это полезно при работе с реальными данными.
👉 @KodBlog
IN и EXISTS в SQL:IN- Пишется проще
- Загружает все совпавшие ID в память
- Тормозит на больших таблицах (например, Customers)
- Может плохо работать без индексов
- В случае
NOT IN падает, если подзапрос возвращает NULLEXISTS- Останавливается на первом совпадении
- Лучше дружит с индексами
- Эффективнее при коррелированных подзапросах
- Корректно обходит
NULL- По производительности
- На маленьких выборках: разница минимальна
- На больших: чаще выигрывает
EXISTS- В коррелированных подзапросах: почти всегда лучше
EXISTSIN должен вычислить и сохранить весь результат подзапроса.EXISTS просто проверяет — существует ли строка, и идёт дальше.Современные оптимизаторы умеют уравнивать разницу, но понимать это полезно при работе с реальными данными.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤6🍌2
В dotnet 9 появился обобщённый
Во многих случаях нужно хранить пары ключ-значение с сохранением порядка и быстрым поиском по ключу. Теперь это можно делать с помощью обобщённого
👉 @KodBlog
OrderedDictionary Во многих случаях нужно хранить пары ключ-значение с сохранением порядка и быстрым поиском по ключу. Теперь это можно делать с помощью обобщённого
OrderedDictionary в .NET 9.Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤3🔥1
С неявными преобразованиями в
👉 @KodBlog
Span<T> в .NET 10 теперь можно передавать массивы напрямую в методы, которые ожидают Span<T> или ReadOnlySpan<T>, без вызова .AsSpan(). Это делает высокопроизводительный код без аллокаций чище и безопаснее. Очень удобноPlease open Telegram to view this post
VIEW IN TELEGRAM
👍6😁4🔥2❤1
Dictionary Expressions в C#?
Сейчас это предложение в статусе champion (ссылка ниже) и продолжение фичи Collection Expressions из C# 12.
Что думаете?👎 или 👍
Предложение Dictionary Expressions
👉 @KodBlog
Сейчас это предложение в статусе champion (ссылка ниже) и продолжение фичи Collection Expressions из C# 12.
Что думаете?
Предложение Dictionary Expressions
Please open Telegram to view this post
VIEW IN TELEGRAM
👍40🥴9👎5❤2🤔2