Небольшая деталь, но именно она делает работу с данными точной и предсказуемой
Не вызывай несколько OrderBy подряд. Каждый новый OrderBy пересортирует коллекцию заново и предыдущая сортировка пропадет. Для дополнительного критерия сортировки используй ThenBy.
Плохой вариант:
Правильный вариант:
👉 @KodBlog
Не вызывай несколько OrderBy подряд. Каждый новый OrderBy пересортирует коллекцию заново и предыдущая сортировка пропадет. Для дополнительного критерия сортировки используй ThenBy.
Плохой вариант:
products
.OrderBy(x => x.Name)
.OrderBy(x => x.Price) // всё пересортирует по цене
Правильный вариант:
products
.OrderBy(x => x.Name)
.ThenBy(x => x.Price)
Please open Telegram to view this post
VIEW IN TELEGRAM
❤17👍13
Скрипт PowerShell для переименования проектов .NET
Переименовать проект .NET - утомительное занятие. Вам придётся переименовать файлы и папки, а также заменить содержимое в файлах, например пространство имён или путь в файлах .sln.
Следующий скрипт PowerShell, переименует файлы и папки и заменит содержимое в файлах:
👉 @KodBlog
Переименовать проект .NET - утомительное занятие. Вам придётся переименовать файлы и папки, а также заменить содержимое в файлах, например пространство имён или путь в файлах .sln.
Следующий скрипт PowerShell, переименует файлы и папки и заменит содержимое в файлах:
$ErrorActionPreference = "Stop"
$rootFolder = Resolve-Path -Path "."
$oldName = "SampleRazorPages"
$newName = "SampleWebApp"
# Переименовываем файлы и папки
foreach ($item in Get-ChildItem -LiteralPath $rootFolder -Recurse | Sort-Object -Property FullName -Descending) {
$itemNewName = $item.Name.Replace($oldName, $newName)
if ($item.Name -ne $itemNewName) {
Rename-Item -LiteralPath $item.FullName -NewName $itemNewName
}
}
# Заменяем содержимое в файлах
foreach ($item in Get-ChildItem $rootFolder -Recurse -Include "*.cmd", "*.cs", "*.csproj", "*.json", "*.md", "*.proj", "*.props", "*.ps1", "*.sln", "*.slnx", "*.targets", "*.txt", "*.vb", "*.vbproj", "*.xaml", "*.xml", "*.xproj", "*.yml", "*.yaml") {
$content = Get-Content -LiteralPath $item.FullName
if ($content) {
$newContent = $content.Replace($oldName, $newName)
Set-Content -LiteralPath $item.FullName -Value $newContent
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥3
Насколько зрел формат dotnet .slnx?
Видел этот вопрос на Reddit. Насколько я понимаю, формат уже готов к использованию. Кто-нибудь его уже применяет?
Пример нового формата .slnx для dotnet → на фото
Это старый скриншот (сейчас уже доступен в стабильной версии Visual Studio), но видно, что новый формат стал заметно менее многословным.
👉 @KodBlog
Видел этот вопрос на Reddit. Насколько я понимаю, формат уже готов к использованию. Кто-нибудь его уже применяет?
Пример нового формата .slnx для dotnet → на фото
Это старый скриншот (сейчас уже доступен в стабильной версии Visual Studio), но видно, что новый формат стал заметно менее многословным.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🤔5
Оптимизация roundtrip в Entity Framework 7
Хорошая оптимизация убирала лишние транзакции, если число вставляемых строк меньше или равно размеру батча 42 у провайдера SQL Server.
👉 @KodBlog
Хорошая оптимизация убирала лишние транзакции, если число вставляемых строк меньше или равно размеру батча 42 у провайдера SQL Server.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3😁3🤔1
This media is not supported in your browser
VIEW IN TELEGRAM
Если вы когда-нибудь работали с базами данных, то знаете про LEFT JOIN (и, соответственно, RIGHT JOIN). Это одна из самых частых операций в SQL.
Но в Entity Framework Core реализовать левое соединение всегда было немного мучением.
Проблема старого LINQ
До .NET 10 в LINQ не было прямого способа выразить LEFT JOIN или RIGHT JOIN.
Вместо этого приходилось городить конструкцию через GroupJoin + DefaultIfEmpty, чтобы сохранить строки из левой таблицы даже при отсутствии совпадений.
Это работало, но выглядело громоздко и плохо читалось.
Пример (старый способ)
Генерируемый SQL:
Метод-синтаксис был ещё менее читаем — GroupJoin, SelectMany, DefaultIfEmpty и прочие танцы с бубном.
Новое в .NET 10: LeftJoin и RightJoin
Теперь в LINQ появились встроенные методы LeftJoin() и RightJoin(), которые наконец-то делают ровно то, что от них ожидаешь.
EF Core корректно транслирует их в SQL-запрос с LEFT JOIN или RIGHT JOIN.
Пример LeftJoin
Результирующий SQL тот же, что и раньше, но код стал в разы короче и понятнее.
Теперь сразу видно намерение: LeftJoin - значит левое соединение.
RightJoin
RightJoin делает обратное: сохраняет все строки из правой таблицы, добавляя данные из левой, если они есть.
EF Core транслирует это в RIGHT JOIN.
SQL:
Несколько советов:
- В проекции защитите сторону, допускающую null:
- Сохраняйте проекции небольшими, чтобы не извлекать больше столбцов, чем необходимо;
- Добавляйте индексы по ключам объединений для улучшения планов запросов.
👉 @KodBlog
Но в Entity Framework Core реализовать левое соединение всегда было немного мучением.
Проблема старого LINQ
До .NET 10 в LINQ не было прямого способа выразить LEFT JOIN или RIGHT JOIN.
Вместо этого приходилось городить конструкцию через GroupJoin + DefaultIfEmpty, чтобы сохранить строки из левой таблицы даже при отсутствии совпадений.
Это работало, но выглядело громоздко и плохо читалось.
Пример (старый способ)
var query =
from product in dbContext.Products
join review in dbContext.Reviews on product.Id equals review.ProductId into reviewGroup
from subReview in reviewGroup.DefaultIfEmpty()
orderby product.Id, subReview.Id
select new
{
ProductId = product.Id,
product.Name,
product.Price,
ReviewId = (int?)subReview.Id ?? 0,
Rating = (int?)subReview.Rating ?? 0,
Comment = subReview.Comment ?? "N/A"
};
Генерируемый SQL:
SELECT
p."Id" AS "ProductId",
p."Name",
p."Price",
COALESCE(r."Id", 0) AS "ReviewId",
COALESCE(r."Rating", 0) AS "Rating",
COALESCE(r."Comment", 'N/A') AS "Comment"
FROM "Products" AS p
LEFT JOIN "Reviews" AS r ON p."Id" = r."ProductId"
ORDER BY p."Id", COALESCE(r."Id", 0)
Метод-синтаксис был ещё менее читаем — GroupJoin, SelectMany, DefaultIfEmpty и прочие танцы с бубном.
Новое в .NET 10: LeftJoin и RightJoin
Теперь в LINQ появились встроенные методы LeftJoin() и RightJoin(), которые наконец-то делают ровно то, что от них ожидаешь.
EF Core корректно транслирует их в SQL-запрос с LEFT JOIN или RIGHT JOIN.
Пример LeftJoin
var query = dbContext.Products
.LeftJoin(
dbContext.Reviews,
product => product.Id,
review => review.ProductId,
(product, review) => new
{
ProductId = product.Id,
product.Name,
product.Price,
ReviewId = (int?)review.Id ?? 0,
Rating = (int?)review.Rating ?? 0,
Comment = review.Comment ?? "N/A"
})
.OrderBy(x => x.ProductId)
.ThenBy(x => x.ReviewId);
Результирующий SQL тот же, что и раньше, но код стал в разы короче и понятнее.
Теперь сразу видно намерение: LeftJoin - значит левое соединение.
RightJoin
RightJoin делает обратное: сохраняет все строки из правой таблицы, добавляя данные из левой, если они есть.
EF Core транслирует это в RIGHT JOIN.
var query = dbContext.Reviews
.RightJoin(
dbContext.Products,
review => review.ProductId,
product => product.Id,
(review, product) => new
{
ProductId = product.Id,
product.Name,
product.Price,
ReviewId = (int?)review.Id ?? 0,
Rating = (int?)review.Rating ?? 0,
Comment = review.Comment ?? "N/A"
});
SQL:
SELECT
p."Id" AS "ProductId",
p."Name",
p."Price",
COALESCE(r."Id", 0) AS "ReviewId",
COALESCE(r."Rating", 0) AS "Rating",
COALESCE(r."Comment", 'N/A') AS "Comment"
FROM "Reviews" AS r
RIGHT JOIN "Products" AS p ON r."ProductId" = p."Id"
Несколько советов:
- В проекции защитите сторону, допускающую null:
review.Comment ?? "N/A";- Сохраняйте проекции небольшими, чтобы не извлекать больше столбцов, чем необходимо;
- Добавляйте индексы по ключам объединений для улучшения планов запросов.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥6
Краткое обновление по .NET 10 — версия готовится к выходу и приносит много интересного. Ниже главное, что удалось собрать.
✅ Подтверждённые изменения:
Версия .NET 10 получит статус LTS (Long-Term Support) с поддержкой несколько лет.
Основные улучшения в рантайме: оптимизация JIT, улучшенная инлайнинг/девиртуализация, улучшения для struct-аргументов.
Новое в C# 14: поддержка модификаторов параметров в лямбдах (ref, in, out), расширенные возможности field-ключевого слова, «extension blocks», null-conditional assignment и др.
В ASP.NET Core / Blazor: улучшения производительности, новые возможности для WebAssembly, улучшенная валидация форм и др.
Несколько оговорок:
Хотя вы могли увидеть сообщение «.NET 10 уже вышел сегодня», официальная GA-дата запланирована на 11 ноября 2025.
InfoQ
Сейчас доступны версии RC (Release Candidate) с поддержкой «go-live».
Не все анонсированные функции ещё подтверждены полностью либо ещё не вошли в стабильную версию.
👉 @KodBlog
Версия .NET 10 получит статус LTS (Long-Term Support) с поддержкой несколько лет.
Основные улучшения в рантайме: оптимизация JIT, улучшенная инлайнинг/девиртуализация, улучшения для struct-аргументов.
Новое в C# 14: поддержка модификаторов параметров в лямбдах (ref, in, out), расширенные возможности field-ключевого слова, «extension blocks», null-conditional assignment и др.
В ASP.NET Core / Blazor: улучшения производительности, новые возможности для WebAssembly, улучшенная валидация форм и др.
Несколько оговорок:
Хотя вы могли увидеть сообщение «.NET 10 уже вышел сегодня», официальная GA-дата запланирована на 11 ноября 2025.
InfoQ
Сейчас доступны версии RC (Release Candidate) с поддержкой «go-live».
Не все анонсированные функции ещё подтверждены полностью либо ещё не вошли в стабильную версию.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5🔥5👍4
This media is not supported in your browser
VIEW IN TELEGRAM
Понимай любую кодовую базу за секунды прямо в VS Code 🤯
Это расширение превращает весь твой проект в наглядную архитектурную визуализацию / показывает, как всё связано, двигается и зависит друг от друга.
Идеально, когда ты подключаешься к новому репозиторию или возвращаешься к старому.
Что делать:
1. Установи расширение Swark
2. Открой Command Palette (Ctrl + Shift + P)
3. Введи “Swark: Create Architecture Diagram” и выбери команду
4. Укажи корневую папку проекта
👉 @KodBlog
Это расширение превращает весь твой проект в наглядную архитектурную визуализацию / показывает, как всё связано, двигается и зависит друг от друга.
Идеально, когда ты подключаешься к новому репозиторию или возвращаешься к старому.
Что делать:
1. Установи расширение Swark
2. Открой Command Palette (Ctrl + Shift + P)
3. Введи “Swark: Create Architecture Diagram” и выбери команду
4. Укажи корневую папку проекта
Please open Telegram to view this post
VIEW IN TELEGRAM
❤14🔥5👎1
.NET 10 уже вышел!
Вот главные обновления по ключевым направлениям:
Нужна стартовая точка под .NET 10? Пора обновляться.
👉 @KodBlog
Вот главные обновления по ключевым направлениям:
C# 14
— расширяемые члены, свойства с полями, implicit spans и обновлённый nameof с поддержкой лямбд. Код стал чище и лаконичнее.
ASP.NET Core
— улучшенная поддержка OpenAPI, встроенная валидация для Minimal API, Server-Sent Events (SSE) и аутентификация с passkey.
EF Core
— добавлен поиск по векторам в SQL, улучшен LINQ–SQL перевод, появились Complex Types и полнотекстовый поиск в Cosmos DB.
Runtime
— прокачанный JIT-компилятор, больше stack allocation, поддержка AVX10.2 и улучшенный NativeAOT — приложения стали легче и быстрее.
Библиотеки
— новые криптографические API, свежие опции для JSON-сериализации, новый WebSocketStream API и ускоренная работа с ZipArchive.
SDK
— апдейты для file-based apps, поддержка контейнеров в консольных приложениях, tab-completion и команда dotnet tool exec.
Aspire
— полноценная поддержка Python и JS, деплой через Aspire Do, контейнеры как артефакты и новый AppHost CLI.
.NET MAUI
— улучшена диагностика и телеметрия верстки, добавлен XAML source generator, обновлён MediaPicker и шаблон Aspire service-defaults.
Нужна стартовая точка под .NET 10? Пора обновляться.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤18👍9👏2🥴1
Похоже, Entity Framework Core с .SqlQuery становится моим новым основным способом доступа к данным.
По моим неофициальным замерам, производительность выше, чем у Dapper, и при этом всё гораздо проще.
Чуть-чуть медленнее, чем чистый
DbContext при этом остаётся максимально лёгким.
👉 @KodBlog
По моим неофициальным замерам, производительность выше, чем у Dapper, и при этом всё гораздо проще.
Чуть-чуть медленнее, чем чистый
ADO.NET, но разница минимальная.DbContext при этом остаётся максимально лёгким.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20👍9❤7
Extension members в C# 14, пожалуй, лучшее, что Microsoft добавила в язык. Теперь можно писать такой чистый и лаконичный код.
👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🥴29👍12🔥7🤔3👏1
Новая версия AsyncAwaitBestPractices v10.0.0
✅ Добавлена поддержка .NET 10
Та самая библиотека async/await, которую все любят, теперь собрана и оптимизирована под .NET 10.
👉 @KodBlog
Та самая библиотека async/await, которую все любят, теперь собрана и оптимизирована под .NET 10.
Please open Telegram to view this post
VIEW IN TELEGRAM
GitHub
GitHub - TheCodeTraveler/AsyncAwaitBestPractices: Extensions for System.Threading.Tasks.Task and System.Threading.Tasks.ValueTask
Extensions for System.Threading.Tasks.Task and System.Threading.Tasks.ValueTask - TheCodeTraveler/AsyncAwaitBestPractices
🥴7👍5🔥2
Оптимизация запроса в EF Core снизила время выполнения с 30 секунд до 30 миллисекунд.
Вот какие шаги помогли
Исходный запрос был из реального проекта соцсети.
Сущности и связи:
Users — у каждого много постов и комментариев
Comments — привязаны к юзеру и посту
Categories — у постов есть категория
Posts — имеют категорию и множество лайков
Likes — относятся к конкретному посту
Задача:
Выбрать топ 5 пользователей, которые оставили больше всего комментариев за последние 7 дней под постами категории .NET.
Для каждого нужно вернуть:
- UserId
- Username
- количество комментариев (только под .NET постами за последние 7 дней)
- топ 3 .NET поста по лайкам, которые этот пользователь чаще всего комментировал (PostId, LikesCount)
Что было сделано для ускорения:
- Предфильтрация пользователей
- Ограничение до топ-5
- Сокращение числа JOIN
- Проекция только нужных полей
- Формирование результата в одном запросе
- Использование AsSplitQuery
- Трехфазный подход
- Двухфазный подход
Подробности можно посмотреть здесь
👉 @KodBlog
Вот какие шаги помогли
Исходный запрос был из реального проекта соцсети.
Сущности и связи:
Users — у каждого много постов и комментариев
Comments — привязаны к юзеру и посту
Categories — у постов есть категория
Posts — имеют категорию и множество лайков
Likes — относятся к конкретному посту
Задача:
Выбрать топ 5 пользователей, которые оставили больше всего комментариев за последние 7 дней под постами категории .NET.
Для каждого нужно вернуть:
- UserId
- Username
- количество комментариев (только под .NET постами за последние 7 дней)
- топ 3 .NET поста по лайкам, которые этот пользователь чаще всего комментировал (PostId, LikesCount)
Что было сделано для ускорения:
- Предфильтрация пользователей
- Ограничение до топ-5
- Сокращение числа JOIN
- Проекция только нужных полей
- Формирование результата в одном запросе
- Использование AsSplitQuery
- Трехфазный подход
- Двухфазный подход
Подробности можно посмотреть здесь
Please open Telegram to view this post
VIEW IN TELEGRAM
🥴10❤6👍2😁1
Media is too big
VIEW IN TELEGRAM
WinForms приложения на .NET Framework можно переехать в web на .NET 9+ и задеплоить в Azure App Services через Visual Studio и copilot за пару минут.
Вся логика приложения и бизнес-код сохраняются.
Сочетание Visual Studio 2026 и GitHub Copilot творит вещи.
👉 @KodBlog
Вся логика приложения и бизнес-код сохраняются.
Сочетание Visual Studio 2026 и GitHub Copilot творит вещи.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯20👍5🥴4🤔3😁1
Ты уже смотрел на новый IExceptionHandler?
Исключения как-то обрабатывать все равно нужно.
IExceptionHandler реализует паттерн с префиксом Try-.
Ты сам решаешь, какие исключения обрабатывать.
Чтобы сообщить middleware, что ты обработал исключение, нужно вернуть true.
Так что же делает это таким интересным?
Можно выстраивать несколько обработчиков исключений в цепочку, и они будут вызываться по очереди.
Первый, который успешно обработает исключение, прерывает цепочку.
Вот как использовать это в .NET 10: читать
👉 @KodBlog
Исключения как-то обрабатывать все равно нужно.
IExceptionHandler реализует паттерн с префиксом Try-.
Ты сам решаешь, какие исключения обрабатывать.
Чтобы сообщить middleware, что ты обработал исключение, нужно вернуть true.
Так что же делает это таким интересным?
Можно выстраивать несколько обработчиков исключений в цепочку, и они будут вызываться по очереди.
Первый, который успешно обработает исключение, прерывает цепочку.
Вот как использовать это в .NET 10: читать
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13🔥7👍4👏1
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9🥴5
Вышло новое сравнение популярных подходов для массовой вставки данных в SQL Server. После практических тестов самым быстрым решением оказался SqlBulkCopy. Он требует больше кода и немного ручной настройки, но по скорости уверенно обгоняет альтернативы.
Для PostgreSQL аналогом выступает команда COPY, работающая по схожему принципу и тоже показывающая отличный перфоманс.
Помимо этого протестированы еще пять других методов, включая варианты с EF Core и C#. Полное сравнение доступно по ссылке
👉 @KodBlog
Для PostgreSQL аналогом выступает команда COPY, работающая по схожему принципу и тоже показывающая отличный перфоманс.
Помимо этого протестированы еще пять других методов, включая варианты с EF Core и C#. Полное сравнение доступно по ссылке
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤3👌2👏1😁1