C# Portal | Программирование
13.9K subscribers
1.15K photos
126 videos
29 files
926 links
Присоединяйтесь к нашему каналу и погрузитесь в мир для C#-разработчика

Сотрудничество, реклама: @devmangx

Менеджер: @Spiral_Yuri

РКН: https://clck.ru/3FocB6
Download Telegram
Как использовать enum в C#: объявление, значения и лучшие практики

Разбор использования перечислений в C# с нуля: объявление, задание значений, приведение типов, сравнение, перебор и практики, которые стоит применять в продакшене.

Читать статью здесь: https://bgh.st/djmghy

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🍾1
required string и string? в EF Core — это не просто разница в синтаксисе, это семантика модели и контракт с базой.

- required string → обязательная инициализация в модели + колонка NOT NULL в БД
- string? → допускает null + колонка с NULL в БД

EF Core использует nullable-аннотации и контекст компилятора, чтобы выводить ограничение целостности схемы. Это напрямую влияет на миграции и поведение трекинга изменений.

Важно: доменную модель нужно задавать явно, а бизнес-ограничения дублировать через Fluent API, чтобы исключить расхождения между кодом и схемой базы.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🍾3
Node.js аддоны… на C#? Да.

Native AOT позволяет собирать нативные shared-библиотеки, которые подключаются напрямую через N-API — без node-gyp, без установки Python, без C++-обвязок.

Получается чистая межъязыковая связка через:

* UnmanagedCallersOnly
* LibraryImport
* Span<T>
* zero-alloc UTF-8 маршалинг

Идея — минимальный оверхед между Node.js и нативным кодом при сохранении управляемого кода на C#.

Блог: https://ift.tt/2mz8B1E

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
3🍾2
Идемпотентность — одна из тех вещей, о которых не думаешь, пока один и тот же запрос не выполняется дважды.

Запрос может упасть, превысить таймаут или быть повторён клиентом. С точки зрения клиента это выглядит нормально. На стороне сервера в этот момент одно и то же действие может выполниться повторно. Если речь про создание заказа или проведение платежа, повторное выполнение приводит к неконсистентному состоянию.

Для этого используется идемпотентность.

Операция считается идемпотентной, если многократное выполнение даёт тот же результат, что и однократное. При одном или нескольких одинаковых запросах итоговое состояние системы не должно меняться.

Один из стандартных способов реализации — идемпотентный ключ. Клиент отправляет уникальный ключ вместе с запросом. Сервер сохраняет этот ключ и результат выполнения. При первом запросе он обрабатывает логику. При повторном запросе с тем же ключом обработка не запускается заново, возвращается сохранённый результат.

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

Повторы останавливать не нужно. Нужно исключить повторное выполнение одной и той же операции.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍92🍾2
Глоббинг в C#

Несколько дней назад я сделал резервную копию документов в OneDrive и не заметил, что после завершения все файлы фактически были перенесены туда.

Далее я откатил резервную копию (20 ГБ), и во многих случаях процесс создал дубликаты.

Знание глоббинга позволило написать код для удаления дубликатов (5000+ файлов) и обхода отдельных папок.

Рекомендую уделить время изучению глоббинга.

Код: https://github.com/karenpayneoregon/learning-topics/tree/master/GlobbingApp1

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔31👍1🍾1
CQS и CQRS — это одно и то же?

Не совсем.

CQS (разделение команд и запросов) — это принцип:

команды изменяют состояние, ничего не возвращают

запросы возвращают данные, не изменяют состояние

он применяется на уровне методов и относится к намерению, а не к жёстким правилам.

CQRS строится на этой идее уже на архитектурном уровне. Он разделяет модели чтения и записи ради масштабируемости, ясности и гибкости.

Хочешь посмотреть, как реализовать CQRS на практике?

Вот как: читать

Большинство приложений уже делают это, даже без прямого упоминания CQRS.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🍾2
net-interview-questions.pdf
3.9 MB
𝟭𝟱𝟬 вопросов для подготовки к .NET-интервью

ASP .NET Core, EF Core, C# вопросы

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12👎2🍾1
azure-alphabet.pdf
2.5 MB
Хочешь уверенно работать с Azure как бэкенд-разработчик на .NET?

Кристи потратил 20+ часов, чтобы собрать «Алфавит Azure для тебя:

• Разобраться в 26 ключевых сервисах и концепциях Azure (без воды)
• Понимать, что делает каждый сервис, когда его использовать и зачем он нужен
• Стартовать путь разработки в Azure

Я его скачал и делюсь с вами! ❤️❤️

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
5🍾1
Самый простой способ генерировать PDF-отчёты

Первый выбор — конвертация HTML → PDF.

В большинстве коммерческих проектов используется IronPDF.

Нужен бесплатный вариант:

- Puppeteer Sharp
- headless-версия Chrome

Но ключевая идея важнее конкретного инструмента.

Если есть HTML-шаблон, появляется полный контроль над форматированием.

Можно использовать современный CSS для стилизации HTML-разметки.

Общая схема реализации:

1. MVC-представления и Razor-синтаксис
2. Рендер динамического HTML-контента
3. Передача HTML в PDF-рендерер

Такой подход использовался в нескольких проектах с хорошими результатами.

Нужен пример реализации гибкой PDF-генерации?

Гайд: тут

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🍾1
Совет по LINQ:

Вызывай ToList() после фильтрации, а не до.

Почему?

> В первом случае всё загружается в память до фильтрации
> Во втором — фильтрация происходит на источнике, что лучше для БД или больших коллекций
> Особенно важно при работе с EF Core или API, использующих IQueryable

🎉🎉

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🥴12😁6🤯3🍾1
Что такое Queue<T>?

Queue<T> — это коллекция в C# с принципом FIFO (первым пришёл — первым ушёл).

То есть первый добавленный элемент будет извлечён первым.

Когда использовать?

> Планирование задач
> Очереди на печать
> Обработка сообщений
> Поиск в ширину (BFS) в графах

Пример прикрепил, с вас лайк ❤️

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍131🍾1💋1
Ubuntu 26.04 поставляется с .NET 10 из коробки: новые контейнерные образы -resolute, готовность к Linux 7.0, постквантовая криптография и чистая поддержка cgroup v2.

Native AOT работает быстро: компактные бинарники + ~3 мс запуска. .NET 8/9 доступны через PPA с бэкпортами.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥5🍾4
EF Core имеет заметную просадку производительности при использовании колонок-идентификаторов.

Как это обычно решают ?

В большинстве проектов для первичных ключей используют либо автоинкремент из базы данных, либо GUID.

При вызове метода SaveChanges EF Core возвращает сгенерированное значение идентификатора, которое сформировала база.

В SQL Server EF Core применяет оператор MERGE с предложением OUTPUT, чтобы объединять множественные вставки в один запрос и возвращать новые значения идентификаторов.

Подход рабочий, но у него есть жёсткие ограничения:

- лимит в 2100 параметров: SQL Server допускает максимум 2100 параметров на один запрос. При 14 колонках это примерно 100–200 строк за одну партию. Для 10 000 строк Product это приводит к множеству обходных вызовов к базе.

- стоимость привязки параметров: каждый параметр создаётся, привязывается и отправляется по сети. Для больших объёмов это десятки тысяч параметров.

- нагрузка на отслеживание изменений: после каждой партии EF Core обновляет трекер изменений и присваивает возвращённые идентификаторы объектам.

Это заметно ухудшает производительность при массовых вставках.

При этом часто нет необходимости возвращать идентификаторы сразу после вставки.

Заявленный результат:
10 000 записей Product.

EF Core SaveChanges с возвратом идентификаторов: ~7000 мс.
Оптимизированная вставка: ~200 мс.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍53🍾1
Использование нативной компиляции AOT в .NET для сборки DLL под Windows WinAPI: читать

Я пропустил один момент с AOT: через него можно собирать нативные библиотеки динамической компоновки. Проверил на практике — получаются небольшие стандартные DLL в стиле WinAPI, которые можно вызывать из легаси-приложений.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🍾2
Версионирование API в .NET 10 получило обновление.

Asp.Versioning v10 + встроенная OpenAPI = чистая документация по версиям без дублирования конфигурации и с корректной поддержкой Minimal API и контроллеров.

SwaggerUI + Scalar также стали учитывать версии API.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👏21🍾1
.NET MAUI работает на Linux через GTK4. Команда экспериментирует с этим в maui-labs, и реализация уже выглядит очень полной. Есть Shell, Blazor Hybrid, CollectionView, жесты, анимации. Всё на нативных виджетах GTK4.

https://github.com/dotnet/maui-labs/tree/main/platforms/Linux.Gtk4

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15🍾5
SkiaSharp 4.0 Preview 1 вышел — более быстрый рендеринг, более чистые API и более умное формирование текста для .NET-приложений, которые рисуют… что угодно.

Попробуй и посмотри, на что теперь способны твои графические компоненты: https://ift.tt/k9wTbRv

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🍾2
Я написал два почти одинаковых SQL-запроса.

Один из них оказался быстрее в 451 раз.

Я реализовывал постраничную навигацию через курсор.

И подумал: почему бы не добавить индекс, чтобы ускорить запрос?

Вот здесь всё пошло не по плану.

Есть сканирование индекса через составной индекс. На первый взгляд — всё нормально.

Но запрос стал даже медленнее, чем без индекса.

В чём причина?

Можно было бы подумать, что дело в слишком маленьком объёме данных, где индекс просто не даёт выгоды.

Но дело было не в этом…

А что если использовать сравнение кортежей в SQL?

В итоге индекс начал работать — 0.668 мс.

Оптимизатор запросов не смог корректно понять, можно ли применить составной индекс для построчного сравнения.

Но при сравнении кортежей индекс начал использоваться эффективно.

Если бы я не посмотрел план выполнения запроса, я бы это не понял.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍82🍾2
Стоит ли перестать использовать случайные UUID в .NET?

Классический UUID через Guid.NewGuid() генерируется случайным образом. Для уникальности это отлично, но для базы данных — не лучший вариант.

Из-за случайного порядка появляются:

- дорогие ребалансировки индексов;
- просадка скорости вставки;
- высокая фрагментация.

Поэтому многие перешли на ULID — 128-битный сортируемый идентификатор с сохранением уникальности.

ULID сохраняет временной порядок генерации, благодаря чему лучше работает с индексами.

Но начиная с .NET 9 появился более нативный вариант:

Guid.CreateVersion7()

UUID V7 — это time-ordered UUID с полной совместимостью с Guid, без сторонних пакетов.

Фактически получаете преимущества ULID, но уже встроенные в .NET.

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👌8🔥3🍾1
This media is not supported in your browser
VIEW IN TELEGRAM
Каждый бэкенд-инженер должен уметь ответить на вопрос:

Что произойдёт, если база данных упадёт посреди транзакции?

Причины могут быть разные: отключение питания, сбой оборудования и т.д.

Чтобы не потерять данные, система должна сохранять их на энергозависимом хранилище, например, на диске.

Когда пользователь выполняет транзакцию, база данных делает две вещи:

> записывает данные в отдельный лог
> применяет обновление

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

Запись в лог быстрая, так как это бинарный файл с добавлением только в конец (append-only).
Это исключает затратные операции поиска по файлу.

А если база распределённая?

Тут сложнее — серверам базы нужно координироваться с помощью протокола двухфазной фиксации (2PC).

В этом процессе один из серверов выступает координатором:

> он отправляет всем участникам запрос на коммит

> ждёт подтверждения от всех

> затем сообщает коммитить или откатить транзакцию

👉 @KodBlog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥3❤‍🔥2🍾1