C# Portal | Программирование
14.9K subscribers
912 photos
106 videos
24 files
758 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для C#-разработчика

Связь: @devmangx

РКН: https://clck.ru/3FocB6
Download Telegram
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, чтобы сохранить строки из левой таблицы даже при отсутствии совпадений.
Это работало, но выглядело громоздко и плохо читалось.

Пример (старый способ)

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";
- Сохраняйте проекции небольшими, чтобы не извлекать больше столбцов, чем необходимо;
- Добавляйте индексы по ключам объединений для улучшения планов запросов.

👉 @KodBlog
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
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
Please open Telegram to view this post
VIEW IN TELEGRAM
14🔥5👎1
.NET 10 уже вышел!

Вот главные обновления по ключевым направлениям:

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? Пора обновляться.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
18👍9👏2🥴1
Похоже, Entity Framework Core с .SqlQuery становится моим новым основным способом доступа к данным.

По моим неофициальным замерам, производительность выше, чем у Dapper, и при этом всё гораздо проще.

Чуть-чуть медленнее, чем чистый ADO.NET, но разница минимальная.
DbContext при этом остаётся максимально лёгким.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20👍97
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
Please open Telegram to view this post
VIEW IN TELEGRAM
🥴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
Please open Telegram to view this post
VIEW IN TELEGRAM
🥴106👍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
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯20👍5🥴4🤔3😁1
Ты уже смотрел на новый IExceptionHandler?

Исключения как-то обрабатывать все равно нужно.

IExceptionHandler реализует паттерн с префиксом Try-.
Ты сам решаешь, какие исключения обрабатывать.

Чтобы сообщить middleware, что ты обработал исключение, нужно вернуть true.

Так что же делает это таким интересным?

Можно выстраивать несколько обработчиков исключений в цепочку, и они будут вызываться по очереди.
Первый, который успешно обработает исключение, прерывает цепочку.

Вот как использовать это в .NET 10: читать

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
13🔥7👍4👏1
Решето Эратосфена на C#
(генератор простых чисел)

LINQ, поехали!

👉 @KodBlog
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
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍63👌2👏1😁1
Понимание паттерна Observer это одна из базовых вещей, которую должен знать любой frontend-разработчик.

// Наблюдатели, которые выполняют Update, когда получают уведомление
interface IObserver
{
void Update(string message);
}

// Субъект, который уведомляет подписанных наблюдателей
interface ISubject
{
// Регистрация, удаление и уведомление наблюдателей
void Register(IObserver observer);
void Unregister(IObserver observer);
void Notify(string message);
}

// Конкретная реализация субъекта, который рассылает обновления подписчикам
class ConcreteSubject : ISubject
{
private readonly List<IObserver> observers = new();

public void Register(IObserver observer)
{
observers.Add(observer);
}

public void Unregister(IObserver observer)
{
observers.Remove(observer);
}

public void Notify(string message)
{
foreach (var observer in observers)
{
observer.Update(message);
}
}
}

// Конкретная реализация наблюдателя, который реагирует на уведомления субъекта
class ConcreteObserver : IObserver
{
private readonly string name;

public ConcreteObserver(string name)
{
this.name = name;
}

public void Update(string message)
{
Console.WriteLine($"{name} получил сообщение: {message}");
}
}

// Создаем субъект и наблюдателей
var subject = new ConcreteSubject();
var observer1 = new ConcreteObserver("Наблюдатель 1");
var observer2 = new ConcreteObserver("Наблюдатель 2");

// Подписываем наблюдателей на субъект
subject.Register(observer1);
subject.Register(observer2);

// Субъект меняет состояние и уведомляет подписчиков
subject.Notify("Состояние изменилось.");
subject.Notify("Доступно новое обновление.");


👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
10👍5😁4
Это приложение прям отличный вариант для разработчиков. Показывает, какие порты у тебя открыты, и позволяет закрыть любой в один клик.

Опенсорсное и работает на Windows, Linux и macOS.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
15🔥6👏1😁1🤔1
Есть два способа настроить оптимистичный контроль конкурентности в EF Core:

1. Использовать атрибут [Timestamp] в модели сущности

2. Определить поле row version через Fluent API

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍3🌚1
Производительность платежной системы в проде была увеличена примерно в 15 раз — всего одной строкой кода в EF Core

Система обрабатывает массовые платежи, разбивая один запрос на множество аккаунтов получателей.

В тестах всё работало нормально, но при переходе в прод с реальными объёмами данных API стал тратить секунды на обработку одного запроса по нескольким тысячам счетов.

Каждый платежный запрос делает выборку из таблицы payment_accounts, чтобы определить счета, которые еще не были полностью оплачены.

Тест на 19 000 аккаунтов в SQL Server показал время обработки: 8.22 секунды.

Требование SLA (p99): 1 секунда.
API был примерно в 8 раз медленнее порога SLA.

Основная проблема оказалась в методе SaveChangesAsync.

EF Core умеет группировать несколько вставок, но база данных все равно выполняет их по отдельности.

В SQL Server EF Core использует оператор MERGE для массовых вставок, но подход ограничен лимитом SQL-параметров (2100 на батч). Если у сущностей много полей = производительность быстро падает.

После оптимизаций стало понятно, что штатными инструментами EF Core не удастся добиться нужной скорости.

Решением стала библиотека Entity Framework Extensions.

Она даёт простой, гибкий и быстрый способ для bulk-вставок, позволяя вставлять тысячи записей за один запрос к базе.

Методы BulkInsert и BulkInsertOptimized позволяют выполнить массовую вставку буквально одной строкой кода.

С их помощью время вставки удалось снизить до 521 мс, что укладывается в SLA.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👌9👍73🔥1