ExecuteUpdate allows batch updates without tracking overhead. await ctx.Users .Where(u => u.IsActive == false) .ExecuteUpdateAsync(p => p.SetProperty(x => x.IsDeleted, true)); It’s fast, clean, and ideal for big-data operations.
Category: .NET
Every Async Method Should Accept CancellationToken
CancellationToken prevents zombie tasks and ensures graceful shutdown. public Task RunAsync(CancellationToken ct) It is a must-have for cloud-native workloads.
Lightning-Fast Lookups in .NET Using MemoryCache
MemoryCache provides a simple and fast in-memory caching solution. var item = cache.GetOrCreate(“users”, entry => { entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10); return repo.GetUsers(); }); Ideal for configuration, lookups, and session data.
Boost Async Performance in .NET with ConfigureAwait(false)
Using ConfigureAwait(false) can significantly reduce context-switching overhead in non-UI .NET applications. This is essential for APIs, background services, and any high-throughput async pipeline. await http.SendAsync(req).ConfigureAwait(false); It lowers CPU usage, avoids deadlocks, and improves overall async performance.
Clean Minimal APIs in .NET – Automatic DTO Binding Explained
Minimal APIs provide automatic DTO binding, eliminating unnecessary boilerplate. app.MapPost(“/login”, (LoginRequest req) => { return Results.Ok($”Welcome {req.Email}”); }); This improves readability, reduces errors, and works perfectly with endpoint filters.
Write Cleaner Business Logic Using C# Switch Expressions
Switch expressions simplify complex branching logic and make code more readable. var price = plan switch { “free” => 0, “pro” => 19, “biz” => 49, _ => throw new Exception(“Unknown plan”) }; They are ideal for pricing models, rules engines, and state transitions.
EF Core Performance Boost: Use AsNoTracking() When Reading Data
For read-heavy queries, AsNoTracking() provides massive performance improvements. var users = await ctx.Users.AsNoTracking().ToListAsync(); It avoids adding entities to the change tracker, improving speed by 30–50%.
Use IAsyncEnumerable for Streaming Data in .NET
IAsyncEnumerable allows true async streaming, reducing memory usage. await foreach (var user in repo.GetAllAsync()) Console.WriteLine(user.Name); Perfect for large datasets and high-throughput APIs.
Why C# Record Types Are Perfect for Modern DTOs
Records offer immutability, value semantics, and minimal syntax. public record UserDto(int Id, string Name, string Email); They are ideal for APIs, events, and data-transfer layers.
Improve .NET Logging with Structured Log Messages
Structured logs allow smarter querying and cleaner search results. logger.LogInformation(“User {UserId} logged in”, id); They improve observability, diagnostics, and production monitoring.
Never Write Retry Logic Again – Use Polly in .NET
Polly provides retry, timeout, fallback, and circuit-breaker patterns. var result = await Policy .Handle() .RetryAsync(3) .ExecuteAsync(() => CallApi()); It’s the gold standard for resilience in .NET microservices.
The One DI Rule You Must Not Break: Avoid Injecting Scoped into Singleton
Mixing Scoped services inside Singletons causes threading issues and hidden bugs. Always match lifetime scopes properly to avoid race conditions and stale state.
Stop Calling ToList() Too Early – Improve LINQ Performance
Calling ToList() too early forces premature execution. // Bad var items = db.Users.ToList().Where(…); // Good var items = db.Users.Where(…).ToList(); Let the database handle filtering and execution.
Build Clean Background Services with IHostedService in .NET
BackgroundService enables clean, scalable background processing. protected override async Task ExecuteAsync(CancellationToken ct) { while (!ct.IsCancellationRequested) { await DoWork(); await Task.Delay(1000, ct); } } It works perfectly in cloud-native environments.
Cleaner .NET APIs Using IEndpointFilter for Validation
Endpoint filters reduce validation noise in Minimal APIs. public class ValidateFilter : IEndpointFilter { public Task<object?> InvokeAsync(EndpointFilterInvocationContext ctx, EndpointFilterDelegate next) { var model = ctx.GetArgument(0); Validator.ValidateObject(model, new()); return next(ctx); } } They keep endpoints clean, reusable, and testable.



