C# (C Sharp) programming
По всем вопросам- @notxxx1 Реестр РКН: https://clck.ru/3Fk3kb #VRHSZ
إظهار المزيد📈 نظرة تحليلية على قناة تيليجرام C# (C Sharp) programming
تُعد قناة C# (C Sharp) programming (@csharp_ci) في القطاع اللغوي الروسية لاعباً نشطاً. يضم المجتمع حالياً 18 127 مشتركاً، محتلاً المرتبة 7 041 في فئة التكنولوجيات والتطبيقات والمرتبة 36 302 في منطقة روسيا.
📊 مؤشرات الجمهور والحراك
منذ تأسيسه في невідомо، حقق المشروع نمواً سريعاً وجمع 18 127 مشتركاً.
بحسب آخر البيانات بتاريخ 29 أغسطس, 2026، تحافظ القناة على نشاط مستقر. خلال آخر 30 يوماً تغيّر عدد الأعضاء بمقدار -78، وفي آخر 24 ساعة بمقدار -7، مع بقاء الوصول العام مرتفعاً.
- حالة التحقق: غير موثّقة
- معدل التفاعل (ER): يبلغ متوسط تفاعل الجمهور 15.03%. وخلال أول 24 ساعة من النشر يحصد المحتوى عادةً 7.44% من ردود الفعل نسبةً إلى إجمالي المشتركين.
- وصول المنشورات: يحصل كل منشور على متوسط 2 725 مشاهدة. وخلال اليوم الأول يجمع عادةً 1 348 مشاهدة.
- التفاعلات والاستجابة: يتفاعل الجمهور بانتظام؛ متوسط التفاعلات لكل منشور يبلغ 0.
- الاهتمامات الموضوعية: يركز المحتوى على مواضيع رئيسية مثل .net, api, логика, архитектура, string.
📝 الوصف وسياسة المحتوى
يصف المؤلف القناة بأنها مساحة للتعبير عن الآراء الذاتية:
“По всем вопросам- @notxxx1
Реестр РКН: https://clck.ru/3Fk3kb
#VRHSZ”
بفضل وتيرة التحديث المرتفعة (أحدث البيانات بتاريخ 30 أغسطس, 2026) تحافظ القناة على حداثتها ومستوى وصول مرتفع. وتُظهر التحليلات تفاعلاً نشطاً من الجمهور، ما يجعلها نقطة تأثير مهمة ضمن فئة التكنولوجيات والتطبيقات.
ChangeTracker на сущности с интерфейсом ISoftDeletable
- Если состояние сущности — Deleted
- Меняет его на Modified
- Устанавливает:
- IsDeleted = true
- DeletedOnUtc = DateTime.UtcNow
В итоге:
Вы вызываете обычный:
context.Remove(entity);
А в базе:
- запись не удаляется
- просто помечается как удалённая
Плюсы подхода:
- никакой логики soft delete в сервисах и репозиториях
- единая точка обработки
- чистый доменный код
- безопасное удаление по всему приложению
Важно:
Если у вас есть связанные сущности (navigation properties),
перехватчик нужно дополнительно расширить — каскадное soft-удаление EF Core не делает автоматически.
Soft delete через interceptor — это один из самых чистых production-подходов для EF Core.
#dotnet #EFCore #Backend #Architecture #CSharpThread.Sleep —
готовьтесь к:
- медленным тестам
- flaky-падениям
- ненависти от CI/CD
Решение — Retry Assertion (Polling)
Как работает паттерн:
1. Выполняем команду (Module A)
2. Периодически опрашиваем состояние (Module B)
3. Ждём, пока результат появится
4. Делаем assert
Схема:
- Execute Command (Module A)
- Poll Query (Module B) until result != null
- Assert
Почему это лучше:
- Нет случайных падений
- Тесты работают быстрее
- Полностью детерминированное поведение
- Отлично подходит для async, событий и modular monolith
Главная идея:
Не жди фиксированное время — жди состояние.
Такой подход превращает нестабильные интеграционные тесты в надёжные и быстрые.IServiceProvider.
Внутри неё можно:
- получить любой сервис
- определить текущего пользователя или tenant
- выбрать нужную базу данных
- и только после этого установить строку подключения
Пример
builder.Services.AddDbContext<OrdersDbContext>((sp, o) =>
{
var tenantProvider = sp.GetRequiredService<TenantProvider>();
var connectionString = tenantProvider.GetConnectionString();
o.UseSqlServer(connectionString);
});
Dynamic DbContext configuration - ключевой паттерн для масштабируемых multi-tenant систем.
Если приложение растёт и базы начинают разделяться по клиентам или регионам, этот подход становится стандартом архитектуры.Thread.Sleep — готовьтесь к:
- медленным тестам
- flaky-поведению
- падениям в CI/CD
Решение — не ждать. Опрос (Polling).
Я использую паттерн Retry Assertion для тестирования асинхронного взаимодействия между модулями:
Как это работает:
1. Выполняем команду (Модуль A)
2. Периодически выполняем запрос (Модуль B)
3. Ждём, пока результат появится
4. Делаем assert
Пример:
var userId = await Sender.Send(new RegisterUserCommand(...));
var result = await Poller.WaitAsync(
TimeSpan.FromSeconds(15),
async () =>
{
return await Sender.Send(new GetCustomerQuery(userId));
});
result.Should().NotBeNull();
result.IsSuccess.Should().BeTrue();MigrationsHistoryTable.
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(
connectionString,
sqlOptions =>
{
sqlOptions.MigrationsHistoryTable(
tableName: "MigrationHistory",
schema: "infrastructure"
);
}));
// Теперь EF будет хранить историю миграций в:
// infrastructure.MigrationHistory
public class Order
{
public Order(string customerName, decimal amount)
{
ArgumentException.ThrowIfNullOrWhiteSpace(customerName);
ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount);
CustomerName = customerName;
Amount = amount;
}
public string CustomerName { get; }
public decimal Amount { get; }
}
public async Task RegisterUserAsync(User user, CancellationToken token)
{
_userRepository.Insert(user);
await _unitOfWork.SaveChangesAsync(token);
await _emailService.SendWelcomeEmailAsync(user, token);
await _eventBus.PublishAsync(new UserRegisteredEvent(user.Id), token);
}
Вопрос
Что здесь может пойти не так?
Проблемы
— Пользователь сохранён, но email не отправился
— Email отправился, но событие не опубликовалось
— Событие ушло, а транзакция в БД откатилась
— При ретраях возможны дубли
Чем больше внешних вызовов, тем больше точек отказа и сложнее обработка ошибок.
Решение — Outbox Pattern
Сохраняем пользователя и событие в одной атомарной транзакции:
public async Task RegisterUserAsync(User user, CancellationToken token)
{
_userRepository.Insert(user);
_outbox.Insert(new UserRegisteredEvent(user.Id));
await _unitOfWork.SaveChangesAsync(token);
}
Дальше отдельный процесс:
• читает сообщения из Outbox
• отправляет email
• публикует события
• помечает как обработанные
Результат
— Нет рассинхронизации между БД и внешними сервисами
— Гарантированная доставка событий
— Возможность безопасных повторов
— Простая и надёжная архитектура для распределённых системIHttpClientFactory (и Aspire, если используешь его):
• Service discovery для service-to-service вызовов
• Встроенная устойчивость к сбоям (retry, handling transient errors)
После этого ты просто инжектишь клиент и пишешь бизнес-логику — без ручной магии с сокетами, таймаутами и DNS.
Чистый код. Меньше багов. Больше фокуса на логике.
Полный разбор
context.Carts
.Where(o => o.CreatedOn < DateTime.Now.AddYears(-1))
.ExecuteDelete();
В результате выполняется один SQL DELETE, который напрямую удаляет старые записи в базе — быстро и без промежуточных объектов в памяти.
⚠️ Важно: bulk-операции обходят change tracker EF. Если в контексте уже есть отслеживаемые сущности, состояние может рассинхронизироваться — учитывайте это в логике.
EF Core давно уже не просто ORM, а полноценный инструмент для высоконагруженных систем. И у него есть ещё много фич, которые серьёзно упрощают жизнь разработчику.
Подробнее