В .NET 11 Preview 6 EF Core получил поддержку трансляции нового LINQ-оператора FullJoin в SQL. Теперь запросы могут выполняться целиком на стороне базы данных, без ручных обходных решений.
Сам оператор FullJoin появился в .NET 11 раньше, но сначала работал только для LINQ to Objects. Теперь EF Core умеет преобразовывать его в FULL OUTER JOIN для реляционных провайдеров, которые поддерживают этот оператор.
Это удобно для задач, где нужно сохранить все строки из обеих таблиц, включая несовпавшие: поиск расхождений, сверка данных, объединение нескольких источников или построение отчётов.
Раньше такие запросы часто приходилось собирать вручную из нескольких JOIN и UNION либо писать сырой SQL.
⚠️ Пока это часть .NET 11 Preview 6. До финального релиза в ноябре поведение ещё может измениться.
#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13👍5
В .NET сборщик мусора работает в двух режимах, и выбор между ними влияет на производительность приложения.
Workstation GC рассчитан на клиентские приложения. Он экономнее расходует память и старается не занимать все доступные ядра.
Ещё одна особенность — Background GC. Во время сборки старших поколений он позволяет сократить длительные паузы, выполняя значительную часть работы параллельно с приложением.
Server GC настраивается через свойство ServerGarbageCollection, хотя многие серверные шаблоны уже используют его по умолчанию.
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Кажется, у онлайн-обучения появился формат, которого давно не хватало 👇
Forwarded from Proglib.academy | IT-курсы
Логично, что обучение тоже постепенно приходит к той же модели: не покупать отдельный курс под каждую новую тему, а иметь доступ ко всей библиотеке и выбирать, что актуально именно сейчас.
Такой формат недавно появился и в Proglib Academy. Вместо одного курса — доступ сразу ко всей библиотеке и новым материалам, которые появляются в подписке
Please open Telegram to view this post
VIEW IN TELEGRAM
😁3🥱3
Спор, который не утихает много лет.
Сторонники хранимых процедур говорят: данные уже в базе, меньше сетевых запросов, выше производительность и больше контроля над SQL.
Сторонники логики в приложении отвечают: код проще тестировать, ревьюить, версионировать в Git и переносить между разными СУБД.
На практике многие выбирают компромисс: сложные операции над большими объёмами данных оставляют в базе, а бизнес-правила и оркестрацию — в приложении.
👍 — максимум логики в приложении.
🔥 — сложную логику лучше держать в базе.
И был ли у вас проект, где сотни хранимых процедур со временем превратились в «чёрный ящик», который никто не хотел менять?
#entry_point
Please open Telegram to view this post
VIEW IN TELEGRAM
👍58🔥13
SOLID — это 5 принципов объектно-ориентированного проектирования. Давайте повторим эту базу.
— Single Responsibility Principle (Принцип единственной ответственности)
Каждый класс должен иметь только одну причину для изменения.
Плохо: класс UserManager и сохраняет пользователя в БД, и отправляет email.
Хорошо: UserRepository хранит, EmailService отправляет письма.
— Open/Closed Principle (Принцип открытости/закрытости)
Классы должны быть открыты для расширения, но закрыты для изменения.
Новый функционал добавляем через расширение, а не переписывание старого кода.
Пример: вместо переписывания метода — создаём новый подкласс или внедряем стратегию.
— Liskov Substitution Principle (Принцип подстановки Барбары Лисков)
Объекты подклассов должны работать так же, как объекты родителя.
Если Square наследуется от Rectangle, он должен вести себя как прямоугольник, а не ломать ожидания.
Суть: наследование не должно рушить логику программы.
— Interface Segregation Principle (Принцип разделения интерфейсов)
Лучше много маленьких интерфейсов, чем один огромный.
Плохо: интерфейс IMachine с методами print(), scan(), fax().
Хорошо: IPrinter, IScanner, IFax. Каждый класс реализует только нужное.
— Dependency Inversion Principle (Принцип инверсии зависимостей)
Зависимости должны быть от абстракций, а не от конкретных классов.
Плохо: класс ReportGenerator напрямую вызывает MySQLDatabase.
Хорошо: ReportGenerator работает с интерфейсом Database, а уже конкретная БД подставляется снаружи.
Без SOLID код быстро превращается в спагетти, где одно изменение ломает всё.
#il_люминатор
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18❤5🔥3🥰1👏1
В стремительном темпе разработки важно улавливать ошибки сразу же после правки.
Представьте, что можно запускать тесты каждый раз, когда вы сохраняете файл — без лишних кликов и ожидания.
Команда дня:
dotnet watch test --filter "Category=Unit»
Эта команда активирует «наблюдение» за исходниками проекта и при каждом изменении автоматически запускает только те тесты, которые помечены категорией Unit.
Вы сразу увидите результаты проверки критичных компонентов, не тратя время на полную прогонку всех тестов.
Если вы хотите параллельно следить и за интеграционными тестами, достаточно изменить фильтр:
dotnet watch test --filter "Category=Integration»
Ещё и интегрировать со скриптами и конвейерами проще простого.
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤2
Какую систему нумерации версий предпочитаете и встречали ли экзотические варианты? Делитесь опытом👇
#схема
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Помните те времена, когда каждый метод начинался с целой простыни проверок входных параметров? Копипаста if (string.IsNullOrEmpty(...)) была ежедневной рутиной:
public void ProcessUser(string name, string email, int age)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentException("Value cannot be null or empty.", nameof(name));
if (string.IsNullOrEmpty(email))
throw new ArgumentException("Value cannot be null or empty.", nameof(email));
if (age < 0)
throw new ArgumentOutOfRangeException(nameof(age), "Value must be non-negative.");
// Наконец-то бизнес-логика!
}
Код становился шумным, а реальная логика терялась в океане проверок. Каждый разработчик писал по-своему, сообщения об ошибках отличались, а про опечатки в nameof() вообще молчим.
Теперь всё это превращается в лаконичные однострочники:
public void ProcessUser(string name, string email, int age)
{
ArgumentException.ThrowIfNullOrEmpty(name);
ArgumentException.ThrowIfNullOrEmpty(email);
ArgumentOutOfRangeException.ThrowIfNegative(age);
}
Стандартная библиотека предлагает методы на все случаи жизни:
// Проверки на null
ArgumentNullException.ThrowIfNull(user);
// Числовые диапазоны
ArgumentOutOfRangeException.ThrowIfNegative(temperature);
ArgumentOutOfRangeException.ThrowIfZero(divisor);
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(count);
// Сравнения
ArgumentOutOfRangeException.ThrowIfGreaterThan(progress, 100);
ArgumentOutOfRangeException.ThrowIfLessThan(quantity, 1);
ArgumentOutOfRangeException.ThrowIfEqual(status, Status.Invalid);
ArgumentOutOfRangeException.ThrowIfNotEqual(version, expectedVersion);
Эти методы — не просто синтаксический сахар. Они воплощают принцип fail-fast: обнаруживай проблемы немедленно, не позволяй невалидным данным распространяться по системе.
#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19❤4👾4❤🔥1
Вышел .NET 11 Preview 7. Апдейт затронул почти весь стек: C#, Runtime, SDK, ASP
.NET Core, EF Core, MAUI, F# и Windows Forms.Главное изменение это перевод NativeAOT в режим по умолчанию в CLI ради заметно более быстрого старта приложений.
Из языка подъехали фичи C# 15, среди них паттерны union и помеченные break и continue для управления вложенными циклами.
В библиотеки добавили десятичные типы по стандарту IEEE 754 и шифрование паролем для ZIP.
Стабильный .NET 11 ожидается в ноябре, а пока Preview 7 можно использовать как полигон: проверить свои проекты на новом SDK и заранее найти проблемы с совместимостью.
👍 — тестирую превью
🔥 — до релиза даже не трогаю
#async_news
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥39👍4🤩2
Знакомая боль. Есть вложенные циклы, и из внутреннего нужно прервать или продолжить внешний. Обычный
break выходит только из ближайшего цикла, поэтому приходилось заводить булев флаг и проверять его на каждом уровне, либо прыгать через goto. И то и другое замусоривает логику.В C# 15 у циклов появились метки, а
break и continue научились указывать, какой именно цикл они имеют в виду. Метка ставится прямо на нужный цикл.
outer: for (int row = 0; row < grid.Height; row++)
{
for (int col = 0; col < grid.Width; col++)
{
if (grid[row, col].IsBlocked)
continue outer;
if (grid[row, col].IsGoal)
break outer;
}
}
continue outer переходит к следующей итерации внешнего цикла, а break outer полностью выходит из него, минуя остаток внутреннего. Никаких флагов и подсчёта уровней.Пара нюансов.
break можно нацелить и на цикл, и на switch, а continue только на цикл, ведь продолжать switch нечего. И метка привязывается именно к тому циклу, перед которым стоит, поэтому двусмысленности, как с goto, здесь нет.#sharp_view
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥24🥱3