День 2555. #ЧтоНовенького
EF Core 10 Превращает PostgreSQL в Реляционно-Документную БД. Начало
Современным .NET-приложениям всё чаще требуется хранить данные, которые не помещаются в реляционные таблицы: кастомные поля для каждого клиента, изменяющиеся атрибуты продукта или данные из внешних API. До EF Core 10 обработка таких гибких данных означала неудобные костыли, столбцы с необработанным текстом JSON или разрозненные NoSQL-хранилища.
Посмотрим, как EF Core 10 представляет новый мощный способ сопоставления столбцов JSONB в PostgreSQL с помощью сложных типов. В сочетании с высокооптимизированным механизмом хранения JSONB в PostgreSQL это позволяет создавать чёткие модели гибких данных с изменяющейся схемой без ущерба для производительности или удобства запросов.
Важность JSONB
Традиционные реляционные модели перестают работать, когда вашему приложению необходимо хранить:
- Динамические или специфичные для клиента поля;
- Иерархические или вложенные атрибуты;
- Развивающиеся структуры, которые часто меняются;
- Данные внешних API или метаданные.
Здесь JSONB проявляет свои лучшие качества: вы получаете гибкость схемы, нативное индексирование, быструю обработку запросов и полные гарантии ACID — и всё это внутри реляционного механизма.
JSON или JSONB в PostgreSQL
- Хранение: JSON – текст, JSONB – двоичное дерево;
- Производительность запросов: JSON – медленно, JSONB – быстро;
- Индексы: JSON – нет, JSONB – GIN/GiST;
- Дублирующиеся ключи: JSON – сохраняются, JSONB – выигрывает последний;
- Плата за парсинг: JSON – в каждом запросе, JSONB – единожды при вставке.
Итого: всегда используйте JSONB, если только вам не нужно сохранять форматирование, тогда используйте JSON.
EF Core 10 изменяет JSON-сопоставление
До .NET 10 сопоставление JSONB требовало наличия принадлежащих сущностей, что приводило к:
- Запутанной семантике принадлежащих типов,
- Теневым первичным ключам,
- Многословной конфигурации,
- Отсутствию поддержки ExecuteUpdate.
Решение для .NET 10: Сложные типы
EF Core 10 представляет сложные типы, предоставляющие:
- Семантику типов-значений,
- Более чистую конфигурацию,
- Автоматические вложенные коллекции,
- Полноценную трансляцию LINQ в JSONB,
- Массовое обновление JSON с помощью ExecuteUpdate,
- Опциональные сложные типы (Address?).
Пример конфигурации:
Вот и всё - EF Core автоматически обрабатывает вложенные структуры.
Запросы к JSONB в EF Core 10
EF Core теперь транслирует сложные LINQ-запросы напрямую в операторы JSONB, такие как
Фильтр по атрибуту JSON:
Фильтр по вложенному числовому полю:
Запрос JSON-массивов:
Массовое обновление JSON с помощью ExecuteUpdate. EF Core 10 обеспечивает реальную поддержку массового обновления JSONB:
Сравнение производительности (10000 записей)
Загрузка+SaveChanges - 5–10с, 10000 запросов
ExecuteUpdate - 100–200мс, 1 запрос
Это значительное улучшение для счётчиков аналитики, обновлений статуса, изменений метаданных и т.д.
Окончание следует…
Источник: https://trailheadtechnology.com/ef-core-10-turns-postgresql-into-a-hybrid-relational-document-db/
EF Core 10 Превращает PostgreSQL в Реляционно-Документную БД. Начало
Современным .NET-приложениям всё чаще требуется хранить данные, которые не помещаются в реляционные таблицы: кастомные поля для каждого клиента, изменяющиеся атрибуты продукта или данные из внешних API. До EF Core 10 обработка таких гибких данных означала неудобные костыли, столбцы с необработанным текстом JSON или разрозненные NoSQL-хранилища.
Посмотрим, как EF Core 10 представляет новый мощный способ сопоставления столбцов JSONB в PostgreSQL с помощью сложных типов. В сочетании с высокооптимизированным механизмом хранения JSONB в PostgreSQL это позволяет создавать чёткие модели гибких данных с изменяющейся схемой без ущерба для производительности или удобства запросов.
Важность JSONB
Традиционные реляционные модели перестают работать, когда вашему приложению необходимо хранить:
- Динамические или специфичные для клиента поля;
- Иерархические или вложенные атрибуты;
- Развивающиеся структуры, которые часто меняются;
- Данные внешних API или метаданные.
Здесь JSONB проявляет свои лучшие качества: вы получаете гибкость схемы, нативное индексирование, быструю обработку запросов и полные гарантии ACID — и всё это внутри реляционного механизма.
JSON или JSONB в PostgreSQL
- Хранение: JSON – текст, JSONB – двоичное дерево;
- Производительность запросов: JSON – медленно, JSONB – быстро;
- Индексы: JSON – нет, JSONB – GIN/GiST;
- Дублирующиеся ключи: JSON – сохраняются, JSONB – выигрывает последний;
- Плата за парсинг: JSON – в каждом запросе, JSONB – единожды при вставке.
Итого: всегда используйте JSONB, если только вам не нужно сохранять форматирование, тогда используйте JSON.
EF Core 10 изменяет JSON-сопоставление
До .NET 10 сопоставление JSONB требовало наличия принадлежащих сущностей, что приводило к:
- Запутанной семантике принадлежащих типов,
- Теневым первичным ключам,
- Многословной конфигурации,
- Отсутствию поддержки ExecuteUpdate.
Решение для .NET 10: Сложные типы
EF Core 10 представляет сложные типы, предоставляющие:
- Семантику типов-значений,
- Более чистую конфигурацию,
- Автоматические вложенные коллекции,
- Полноценную трансляцию LINQ в JSONB,
- Массовое обновление JSON с помощью ExecuteUpdate,
- Опциональные сложные типы (Address?).
Пример конфигурации:
modelBuilder.Entity<Product>()
.ComplexProperty(p => p.Specs, b => b.ToJson());
Вот и всё - EF Core автоматически обрабатывает вложенные структуры.
Запросы к JSONB в EF Core 10
EF Core теперь транслирует сложные LINQ-запросы напрямую в операторы JSONB, такие как
->, ->>, @>.Фильтр по атрибуту JSON:
var items = await context.Products
.Where(p => p.Specs.Brand == "Apple")
.ToListAsync();
Фильтр по вложенному числовому полю:
var results = await context.Products
.Where(p => p.Specs.RAM >= 16)
.ToListAsync();
Запрос JSON-массивов:
var items = await context.Products
.Where(p => p.Specs.Features.Contains("Waterproof"))
.ToListAsync();
Массовое обновление JSON с помощью ExecuteUpdate. EF Core 10 обеспечивает реальную поддержку массового обновления JSONB:
await context.Products
.ExecuteUpdateAsync(s =>
s.SetProperty(p => p.Metadata.Views,
p => p.Metadata.Views + 1));
Сравнение производительности (10000 записей)
Загрузка+SaveChanges - 5–10с, 10000 запросов
ExecuteUpdate - 100–200мс, 1 запрос
Это значительное улучшение для счётчиков аналитики, обновлений статуса, изменений метаданных и т.д.
Окончание следует…
Источник: https://trailheadtechnology.com/ef-core-10-turns-postgresql-into-a-hybrid-relational-document-db/
👍24
День 2556. #ЧтоНовенького
EF Core 10 Превращает PostgreSQL в Реляционно-Документную БД. Окончание
Начало
Когда использовать JSONB
- Гибкая схема данных
Метаданные, настройки, определения рабочих процессов, конфигурация.
- Иерархические данные
Вложенные объекты или списки, которые плохо отображаются на реляционные таблицы.
- Часто изменяющиеся данные
Динамические поля, которые изменяются без необходимости миграции.
- Полуструктурированные или внешние данные
Полезные нагрузки веб-хуков, ответы API, интеграции.
- Снепшоты
Журналы аудита, история версий, журналы изменений.
Когда НЕ использовать JSONB
- Стабильные данные основного домена
Реляционные столбцы работают быстрее и обеспечивают соблюдение ограничений.
- Связи по внешним ключам
JSONB не может обеспечить ссылочную целостность.
- Данные с множественными объединениями (JOIN)
Объединения по реляционным полям производительнее извлечений JSON.
- Нагрузки OLTP с высокой частотой записи
Обновление JSONB перезаписывает весь документ.
Правильная индексация JSONB
Без индексации запросы к JSONB быстро деградируют.
Индекс GIN (наиболее частоиспользуемый):
Индекс-выражение для определённого поля:
Используйте GIN-индексы для запросов на вхождение и индексы-выражения для фильтрации по определённым ключам.
Разработка гибридной схемы (рекомендуемый подход)
Наиболее надёжные архитектуры сочетают реляционный и JSONB стили.
Реляционные столбцы для:
- Стабильных полей,
- Часто запрашиваемых атрибутов,
- Соединений и внешних ключей.
JSONB для:
- Необязательных полей,
- Динамических или специфичных для клиента атрибутов,
- Метаданных, настроек и рабочих процессов.
Пример модели
Это даёт вашей схеме безопасность и гибкость.
Сводка производительности
JSONB быстрее для:
- Запросов на вхождение (@>);
- Чтения целых документов;
- Запросов, избегающих нескольких объединений таблиц.
JSONB медленнее для:
- Агрегации больших наборов данных;
- Частных обновлений больших документов;
- Сложной логики объединения (JOIN);
- Запросов, требующих строгих реляционных ограничений.
Практический пример
Конфигурация EF Core:
Запрос:
Массовое обновление:
Итого
EF Core 10 наконец-то предоставляет чистый, мощный и первоклассный способ использования JSONB в PostgreSQL через сложные типы:
- Сложные типы — новый стандарт для сопоставления JSON в .NET 10;
- JSONB идеально подходит для гибких, развивающихся иерархических данных;
- ExecuteUpdate повышает производительность при обновлениях JSON;
- Используйте гибридную реляционную модель + JSONB для оптимальной архитектуры;
- JSONB — мощный инструмент, но не замена реляционному проектированию.
При разумном использовании JSONB - один из наиболее эффективных инструментов, доступных разработчикам .NET для создания современных, гибких приложений.
Источник: https://trailheadtechnology.com/ef-core-10-turns-postgresql-into-a-hybrid-relational-document-db/
EF Core 10 Превращает PostgreSQL в Реляционно-Документную БД. Окончание
Начало
Когда использовать JSONB
- Гибкая схема данных
Метаданные, настройки, определения рабочих процессов, конфигурация.
- Иерархические данные
Вложенные объекты или списки, которые плохо отображаются на реляционные таблицы.
- Часто изменяющиеся данные
Динамические поля, которые изменяются без необходимости миграции.
- Полуструктурированные или внешние данные
Полезные нагрузки веб-хуков, ответы API, интеграции.
- Снепшоты
Журналы аудита, история версий, журналы изменений.
Когда НЕ использовать JSONB
- Стабильные данные основного домена
Реляционные столбцы работают быстрее и обеспечивают соблюдение ограничений.
- Связи по внешним ключам
JSONB не может обеспечить ссылочную целостность.
- Данные с множественными объединениями (JOIN)
Объединения по реляционным полям производительнее извлечений JSON.
- Нагрузки OLTP с высокой частотой записи
Обновление JSONB перезаписывает весь документ.
Правильная индексация JSONB
Без индексации запросы к JSONB быстро деградируют.
Индекс GIN (наиболее частоиспользуемый):
CREATE INDEX idx_specs_gin ON products USING gin (specs);
Индекс-выражение для определённого поля:
CREATE INDEX idx_brand ON products ((specs ->> 'Brand'));
Используйте GIN-индексы для запросов на вхождение и индексы-выражения для фильтрации по определённым ключам.
Разработка гибридной схемы (рекомендуемый подход)
Наиболее надёжные архитектуры сочетают реляционный и JSONB стили.
Реляционные столбцы для:
- Стабильных полей,
- Часто запрашиваемых атрибутов,
- Соединений и внешних ключей.
JSONB для:
- Необязательных полей,
- Динамических или специфичных для клиента атрибутов,
- Метаданных, настроек и рабочих процессов.
Пример модели
public class Product
{
public int Id { get; set; }
public string Category { get; set; } = null!;
public decimal Price { get; set; }
public Specifications Specs { get; set; } = new();
}
Это даёт вашей схеме безопасность и гибкость.
Сводка производительности
JSONB быстрее для:
- Запросов на вхождение (@>);
- Чтения целых документов;
- Запросов, избегающих нескольких объединений таблиц.
JSONB медленнее для:
- Агрегации больших наборов данных;
- Частных обновлений больших документов;
- Сложной логики объединения (JOIN);
- Запросов, требующих строгих реляционных ограничений.
Практический пример
Конфигурация EF Core:
modelBuilder.Entity<Order>(entity =>
{
entity.ComplexProperty(o => o.Metadata, b => b.ToJson());
entity.ComplexCollection(o => o.Items, b => b.ToJson());
});
Запрос:
var orders = await context.Orders
.Where(o => o.Items.Any(i => i.UnitPrice > 100))
.ToListAsync();
Массовое обновление:
await context.Orders
.Where(o => o.Metadata.Status == "Pending")
.ExecuteUpdateAsync(s =>
s.SetProperty(p => p.Metadata.Status, "Processing"));
Итого
EF Core 10 наконец-то предоставляет чистый, мощный и первоклассный способ использования JSONB в PostgreSQL через сложные типы:
- Сложные типы — новый стандарт для сопоставления JSON в .NET 10;
- JSONB идеально подходит для гибких, развивающихся иерархических данных;
- ExecuteUpdate повышает производительность при обновлениях JSON;
- Используйте гибридную реляционную модель + JSONB для оптимальной архитектуры;
- JSONB — мощный инструмент, но не замена реляционному проектированию.
При разумном использовании JSONB - один из наиболее эффективных инструментов, доступных разработчикам .NET для создания современных, гибких приложений.
Источник: https://trailheadtechnology.com/ef-core-10-turns-postgresql-into-a-hybrid-relational-document-db/
👍9👎2
День 2557. #Карьера
Топ Советов по Повышению Продуктивности. Часть 6
Части 1, 2, 3, 4, 5
6. Алиасы команд и скрипты: автоматизируйте свою мышечную память
Быстрый тест: сколько команд вы набираете каждый день?
Для большинства разработчиков это одни и те же действия: запуск сервера разработки, запуск тестов, проверка статуса Git, и т.п. Вы набираете эти команды так часто, что они прочно засели в вашей мышечной памяти.
Секрет продуктивности: каждая повторяющаяся команда — это потраченное впустую время. Не потому, что набор текста медленный (хотя это так), а потому, что каждая команда — это точка принятия решения. «Какой тут флаг? На каком порту работает приложение?» Эти микрорешения накапливаются, превращаясь в сплошную рутину. Автоматизируйте всё, что вы делаете, более двух раз.
1. Алиасы терминала
Добавьте это в ваши .zshrc или .bashrc:
2. Функции для сложных команд
Когда алиасов недостаточно, пишите функции:
Теперь
3. Скрипты для проектов
Создайте папку
Теперь скрипт
4. Автозагрузка
Добавьте скрипт в автозагрузку ОС. В скрипт добавьте обновление ваших репозиториев, открытие браузера с багтрекером, пересборку проектов и т.п.
Дело не столько в скорости. Дело в снижении усталости от принятия решений. Когда вы исключаете микрорешения типа «Какая там была команда?», вы сохраняете умственную энергию для решения реальных проблем. Вы дольше остаётесь в состоянии потока и реже переключаетесь между задачами.
Что автоматизировать:
- Настройка и очистка среды;
- Операции с БД (сброс, заполнение, резервное копирование, восстановление);
- Рабочие процессы развёртывания;
- Генерация кода (новые компоненты, конечные точки API, тесты);
- Задачи очистки (удаление веток, очистка кэша);
- Распространённые команды отладки.
Каждый раз, когда вы вводите сложную команду во второй раз, остановитесь. Создайте алиас или скрипт. Это займет 30 секунд и принесёт дивиденды навсегда. Храните файл
Источник: https://dev.to/thebitforge/top-10-productivity-hacks-every-developer-should-know-151h
Топ Советов по Повышению Продуктивности. Часть 6
Части 1, 2, 3, 4, 5
6. Алиасы команд и скрипты: автоматизируйте свою мышечную память
Быстрый тест: сколько команд вы набираете каждый день?
Для большинства разработчиков это одни и те же действия: запуск сервера разработки, запуск тестов, проверка статуса Git, и т.п. Вы набираете эти команды так часто, что они прочно засели в вашей мышечной памяти.
Секрет продуктивности: каждая повторяющаяся команда — это потраченное впустую время. Не потому, что набор текста медленный (хотя это так), а потому, что каждая команда — это точка принятия решения. «Какой тут флаг? На каком порту работает приложение?» Эти микрорешения накапливаются, превращаясь в сплошную рутину. Автоматизируйте всё, что вы делаете, более двух раз.
1. Алиасы терминала
Добавьте это в ваши .zshrc или .bashrc:
# Git
alias gs='git status'
alias gp='git pull'
alias gpo='git push origin'
alias gc='git commit -m'
alias gco='git checkout'
alias gb='git branch'
# Project
alias proj='cd ~/projects'
alias work='cd ~/projects/work'
alias ..='cd ..'
alias ...='cd ../..'
# Testing
alias run='dotnet run'
alias test='dotnet test'
2. Функции для сложных команд
Когда алиасов недостаточно, пишите функции:
# Новая ветка и пуш
gnb() {
git checkout -b "$1"
git push -u origin "$1"
}
# Быстрый коммит
qc() {
git add .
git commit -m "$1"
git push
}
# Создать папку и перейти в неё
mkcd() {
mkdir -p "$1"
cd "$1"
}
Теперь
gnb feature/new-auth создаст и запушит новую ветку одной командой.3. Скрипты для проектов
Создайте папку
scripts/ в проекте и добавьте частые команды:#!/bin/bash
# scripts/dev-rebuild.sh
echo "Rebuilding environment…"
dotnet clean
dotnet build
dotnet test
dotnet watch run
Теперь скрипт
./scripts/dev-setup.sh пересобирает, тестирует и запускает ваше приложение.4. Автозагрузка
Добавьте скрипт в автозагрузку ОС. В скрипт добавьте обновление ваших репозиториев, открытие браузера с багтрекером, пересборку проектов и т.п.
Дело не столько в скорости. Дело в снижении усталости от принятия решений. Когда вы исключаете микрорешения типа «Какая там была команда?», вы сохраняете умственную энергию для решения реальных проблем. Вы дольше остаётесь в состоянии потока и реже переключаетесь между задачами.
Что автоматизировать:
- Настройка и очистка среды;
- Операции с БД (сброс, заполнение, резервное копирование, восстановление);
- Рабочие процессы развёртывания;
- Генерация кода (новые компоненты, конечные точки API, тесты);
- Задачи очистки (удаление веток, очистка кэша);
- Распространённые команды отладки.
Каждый раз, когда вы вводите сложную команду во второй раз, остановитесь. Создайте алиас или скрипт. Это займет 30 секунд и принесёт дивиденды навсегда. Храните файл
.aliases в репозитории и синхронизируйте его между компьютерами. Лучшие разработчики не просто печатают быстрее — они автоматизируют всё, что не требует размышлений.Источник: https://dev.to/thebitforge/top-10-productivity-hacks-every-developer-should-know-151h
👍11👎1
День 2558. #ВопросыНаСобеседовании
Марк Прайс предложил свой набор из 60 вопросов (как технических, так и на софт-скилы), которые могут задать на собеседовании.
19. Глобализация и локализация
«Объясните, как реализовать глобализацию и локализацию в проекте веб-сайта ASP.NET Core MVC для поддержки нескольких языков и культур?»
Хороший ответ
Глобализация и локализация являются ключевыми факторами при разработке приложений, способных поддерживать несколько языков и культурных форматов. В ASP.NET Core это включает в себя настройку сервисов и промежуточного ПО для поддержки различных культур в целях локализации контента и форматирования данных в соответствии с предпочтениями пользователя.
Для реализации локализации в проекте веб-сайта ASP.NET Core необходимо настроить сервисы в файле Program.cs, добавив поддержку локализации для различных культур:
Далее создадим файлы ресурсов для каждого языка в каталоге
Затем внедрим IStringLocalizer в MVC-контроллеры или компоненты представления для получения локализованных строк:
Преимущества
- Гибкость и расширяемость: Лёгкое добавление поддержки дополнительных языков путем добавления новых файлов ресурсов.
- Улучшенный пользовательский опыт: Пользователи видят контент на предпочитаемом ими языке, что повышает удобство использования.
- Точность культуры: Правильно отформатированные даты, числа и валюты в соответствии с языковыми особенностями пользователя.
Эта конфигурация поддерживает не только контент, отображаемый на стороне сервера, но и может быть расширена для сценариев на стороне клиента с использованием библиотек JavaScript или вызовов API, возвращающих локализованный контент.
Часто встречающийся неправильный ответ
«Для поддержки нескольких языков в веб-приложении можно использовать перевод текста на стороне клиента, используя JavaScript или клиентскую библиотеку».
Почему это неправильно:
- Зависимость от клиентской стороны: Этот подход предполагает чрезмерно упрощённый метод, полагаясь исключительно на перевод на стороне клиента, что может привести к несоответствиям и не обрабатывает рендеринг на стороне сервера или форматирование данных (например, дат и чисел) должным образом.
- Игнорирование возможностей ASP.NET Core: Подход игнорирует встроенную поддержку локализации в ASP.NET Core, которая разработана для интеграции с серверной архитектурой, обеспечивая согласованное сохранение настроек локализации во всём приложении.
- Игнорирование доступности и SEO: Локализация на стороне сервера имеет решающее значение для доступности и поисковой оптимизации - областей, которые рендеринг на стороне клиента не может в полной мере учитывать.
Обычно эта ошибка возникает из-за недостаточного понимания инструментов и конфигураций, предоставляемых ASP.NET Core для обработки локализации и глобализации как на стороне клиента, так и на стороне сервера.
Источник: https://github.com/markjprice/tools-skills-net8/blob/main/docs/interview-qa/readme.md
Марк Прайс предложил свой набор из 60 вопросов (как технических, так и на софт-скилы), которые могут задать на собеседовании.
19. Глобализация и локализация
«Объясните, как реализовать глобализацию и локализацию в проекте веб-сайта ASP.NET Core MVC для поддержки нескольких языков и культур?»
Хороший ответ
Глобализация и локализация являются ключевыми факторами при разработке приложений, способных поддерживать несколько языков и культурных форматов. В ASP.NET Core это включает в себя настройку сервисов и промежуточного ПО для поддержки различных культур в целях локализации контента и форматирования данных в соответствии с предпочтениями пользователя.
Для реализации локализации в проекте веб-сайта ASP.NET Core необходимо настроить сервисы в файле Program.cs, добавив поддержку локализации для различных культур:
// Чтобы использовать RequestCulture
using Microsoft.AspNetCore.Localization;
var builder = WebApplication.CreateBuilder(args);
// Добавляем сервисы локализации
builder.Services.AddLocalization(options =>
options.ResourcesPath = "Resources");
// Настраиваем поддерживаемые культуры
string[] cultures = ["en-US", "fr-FR", "ru-RU"];
builder.Services
.Configure<RequestLocalizationOptions>(opts =>
{
opts.DefaultRequestCulture =
new RequestCulture("ru-RU ");
opts.SupportedCultures = cultures;
opts.SupportedUICultures = cultures;
});
var app = builder.Build();
app.UseRequestLocalization();
app.MapGet("/", (IStringLocalizer<Program> localizer) =>
localizer["WelcomeMessage"]);
app.Run();
Далее создадим файлы ресурсов для каждого языка в каталоге
Resources, назвав их <ClassName>.<Culture>.resx, например, Program.en-US.resx, Program.ru-RU.resx.Затем внедрим IStringLocalizer в MVC-контроллеры или компоненты представления для получения локализованных строк:
public class HomeController : Controller
{
private readonly
IStringLocalizer<HomeController> _localizer;
public HomeController(
IStringLocalizer<HomeController> localizer)
{
_localizer = localizer;
}
public IActionResult Index()
{
ViewData["Message"] = _localizer["HomePageWelcome"];
return View();
}
}
Преимущества
- Гибкость и расширяемость: Лёгкое добавление поддержки дополнительных языков путем добавления новых файлов ресурсов.
- Улучшенный пользовательский опыт: Пользователи видят контент на предпочитаемом ими языке, что повышает удобство использования.
- Точность культуры: Правильно отформатированные даты, числа и валюты в соответствии с языковыми особенностями пользователя.
Эта конфигурация поддерживает не только контент, отображаемый на стороне сервера, но и может быть расширена для сценариев на стороне клиента с использованием библиотек JavaScript или вызовов API, возвращающих локализованный контент.
Часто встречающийся неправильный ответ
«Для поддержки нескольких языков в веб-приложении можно использовать перевод текста на стороне клиента, используя JavaScript или клиентскую библиотеку».
Почему это неправильно:
- Зависимость от клиентской стороны: Этот подход предполагает чрезмерно упрощённый метод, полагаясь исключительно на перевод на стороне клиента, что может привести к несоответствиям и не обрабатывает рендеринг на стороне сервера или форматирование данных (например, дат и чисел) должным образом.
- Игнорирование возможностей ASP.NET Core: Подход игнорирует встроенную поддержку локализации в ASP.NET Core, которая разработана для интеграции с серверной архитектурой, обеспечивая согласованное сохранение настроек локализации во всём приложении.
- Игнорирование доступности и SEO: Локализация на стороне сервера имеет решающее значение для доступности и поисковой оптимизации - областей, которые рендеринг на стороне клиента не может в полной мере учитывать.
Обычно эта ошибка возникает из-за недостаточного понимания инструментов и конфигураций, предоставляемых ASP.NET Core для обработки локализации и глобализации как на стороне клиента, так и на стороне сервера.
Источник: https://github.com/markjprice/tools-skills-net8/blob/main/docs/interview-qa/readme.md
👍2
День 2559. #ЗаметкиНаПолях
Когда для Моделирования Объектов не Обойтись без Методов Расширения
Иногда "обычный" подход к моделированию сущности достигает своего предела, и приходится прибегать к методам расширения.
Проблема
Есть фронтенд-часть, которая позволяет частично обновлять сущность. Представьте, что в JIRA вы можете обновлять заголовок, автора и так далее в одном пользовательском интерфейсе. Для этого не нужен отдельный DTO для каждого варианта использования, достаточно одного DTO, который позволял бы частично обновлять сущность.
Во фронтенде (TypeScript/Angular):
Который используется в DTO:
На бэкэнде это позволяет сделать так:
Затем в методе обновления:
Это работает. Но что, если мы добавим propFour с обнуляемым типом:
Но в UpdateModel мы хотели бы иметь (потому что в случае обновления значение обязательно):
Теперь, если мы попытаемся выполнить:
Мы получим:
Argument type 'int?' is not assignable to parameter type 'int' (Тип аргумента 'int?' не может быть присвоен параметру типа 'int')
Решение
Проблема в том, что мы не можем легко переопределить возможность присвоения значения null в методе GetValueOrDefault. Здесь помогут методы расширения:
Теперь:
работает, как ожидалось.
Источник: https://steven-giesel.com/blogPost/7f6e2ade-b5b9-4de6-a060-281e45b2448e/sometimes-you-just-need-extensions-methods-to-model-your-stuff
Когда для Моделирования Объектов не Обойтись без Методов Расширения
Иногда "обычный" подход к моделированию сущности достигает своего предела, и приходится прибегать к методам расширения.
Проблема
Есть фронтенд-часть, которая позволяет частично обновлять сущность. Представьте, что в JIRA вы можете обновлять заголовок, автора и так далее в одном пользовательском интерфейсе. Для этого не нужен отдельный DTO для каждого варианта использования, достаточно одного DTO, который позволял бы частично обновлять сущность.
Во фронтенде (TypeScript/Angular):
export type Optional<T> = {
hasValue: boolean;
value: T;
};Который используется в DTO:
export type UpdateModel = {
propOne: Optional<number | null>;
propTwo: Optional<string | null>;
propThree: Optional<string>;
};На бэкэнде это позволяет сделать так:
/// <summary>
/// Структура, представляющая необязательное значение
/// </summary>
public readonly record struct
Optional<T>(bool HasValue, T Value)
{
/// <summary>
/// Возвращает значение, если оно есть, либо значение по умолчанию.
/// </summary>
public T GetValueOrDefault(T current)
=> HasValue ? Value : current;
}
Затем в методе обновления:
public void
UpdateEntity(UpdateModel model)
{
PropOne = model.PropOne
.GetValueOrDefault(entity.PropOne);
PropTwo = model.PropTwo
.GetValueOrDefault(entity.PropTwo);
PropThree = model.PropThree
.GetValueOrDefault(entity.PropThree);
}
Это работает. Но что, если мы добавим propFour с обнуляемым типом:
public int? PropFour { get; set; }Но в UpdateModel мы хотели бы иметь (потому что в случае обновления значение обязательно):
public Optional<int> PropFour { get; set; }Теперь, если мы попытаемся выполнить:
PropFour = model.PropFour
.GetValueOrDefault(entity.PropFour);
Мы получим:
Argument type 'int?' is not assignable to parameter type 'int' (Тип аргумента 'int?' не может быть присвоен параметру типа 'int')
Решение
Проблема в том, что мы не можем легко переопределить возможность присвоения значения null в методе GetValueOrDefault. Здесь помогут методы расширения:
public static class OptionalExtensions
{
/// <summary>
/// Возвращает значение, если оно есть, либо значение по умолчанию
/// </summary>
public static T? GetValueOrDefault<T>(
this Optional<T> opt,
T? value) where T : struct
=> opt.HasValue ? opt.Value : value;
}
Теперь:
PropFour = model.PropFour
.GetValueOrDefault(entity.PropFour);
работает, как ожидалось.
Источник: https://steven-giesel.com/blogPost/7f6e2ade-b5b9-4de6-a060-281e45b2448e/sometimes-you-just-need-extensions-methods-to-model-your-stuff