C# (C Sharp) programming
По всем вопросам- @notxxx1 Реестр РКН: https://clck.ru/3Fk3kb #VRHSZ
نمایش بیشتر📈 تحلیل کانال تلگرام C# (C Sharp) programming
کانال C# (C Sharp) programming (@csharp_ci) در بخش زبانی روسی بازیگری فعال است. در حال حاضر جامعه شامل 18 129 مشترک است و جایگاه 7 042 را در دسته فناوری و برنامهها و رتبه 36 294 را در منطقه روسيا دارد.
📊 شاخصهای مخاطب و پویایی
از زمان ایجاد در невідомо، پروژه رشد سریعی داشته و 18 129 مشترک جذب کرده است.
بر اساس آخرین دادهها در تاریخ 28 اوت, 2026، کانال فعالیت پایداری دارد. در ۳۰ روز گذشته تغییر اعضا برابر -66 و در ۲۴ ساعت گذشته برابر -1 بوده و همچنان دسترسی گستردهای حفظ شده است.
- وضعیت تأیید: تأیید نشده
- نرخ تعامل (ER): میانگین تعامل مخاطب 15.26% است و در ۲۴ ساعت نخست پس از انتشار، محتوا معمولاً 7.43% واکنش نسبت به کل مشترکان کسب میکند.
- دسترسی پستها: هر پست به طور میانگین 2 767 بازدید دریافت میکند. در اولین روز معمولاً 1 348 بازدید جمعآوری میشود.
- واکنشها و تعامل: مخاطبان بهطور فعال حمایت میکنند؛ میانگین واکنش به هر پست 0 است.
- علایق موضوعی: محتوا بر موضوعات کلیدی مانند .net, api, логика, архитектура, string تمرکز دارد.
📝 توضیح و سیاست محتوایی
نویسنده این فضا را محل بیان دیدگاههای شخصی توصیف میکند:
“По всем вопросам- @notxxx1
Реестр РКН: https://clck.ru/3Fk3kb
#VRHSZ”
به لطف بهروزرسانیهای پرتکرار (آخرین داده در تاریخ 29 اوت, 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, а полноценный инструмент для высоконагруженных систем. И у него есть ещё много фич, которые серьёзно упрощают жизнь разработчику.
Подробнее