13 Mar 2026 #selfgrowth
Take public transportation at rush hour. You’ll notice a clear pattern.
More than half the people are heads down, headphones on, scrolling.
If we don’t take care of our health, we’ll be depressed, sleep-deprived, deaf, people with the attention span of a fish.
Taking care of our health is the first step towards reinvention. After commuting, scrolling, junk food, and poor sleep, we lack the energy and drive to be creative and have new ideas. That’s when AI will eat us alive, when we’re too drained to imagine and create.
Reading, eating healthy foods, and sleeping well isn’t just self-care. It’s an act of resistance.
13 Mar 2026 #mondaylinks
Hey there.
Here are 5 links I thought were worth sharing this week:
#1. We all might become AI engineers (6min), but we still need to know what to build and how it should work. AI needs hands on the wheel.
#2. AI speeds up coding, but there are plenty of coding activities that aren’t typing (2min). There’s still work for humans.
#3. Last week, another npm package was infected. The interesting part? Someone stole the npm token by injecting a prompt into a GitHub issue (10min). SQL injection isn’t the #1 vulnerability anymore.
#4. If you’re a C# coder using Dapper, be aware of data type conversions that might be slowing down your queries (8min).
#5. If you’ve had a hard time finding a job. You’re not alone. Hiring is as bad as during the pandemic (1min).
Last week, while migrating a legacy app, I wrote about my adventures with Entity Framework Core joining tables (5min) and with Blazor building a component for a HTML editor (4min).
(Bzzz…Radio voice) This email was brought to you by… 10 Surprisingly Simple Ideas That Changed My Life And Could Change Yours Too. This book shares 10 small daily ideas that create big change. I adopted most of them while recovering from burnout
If you’re ready to start small and see big change, check it out.
Until next Friday. Stay coding smartly!
Cesar
11 Mar 2026 #wellness
If you could only do one thing for your health, it should be sleep.
Brian Johnson, the guy trying to live forever, teaches in his videos and interviews to be a professional sleeper.
He’s right when he says nobody teaches us to sleep.
For better sleep, build your life around sleep:
Beyond the basics, Brian’s recent videos taught me to aim for a lower heart rate before sleep. Try journaling, taking deep breaths, or meditation. Slow down before going to bed.
Staying late for my writing streak taught me rest is the best productivity hack. Coffee can’t fix a bad night of sleep. So go to sleep!
11 Mar 2026 #todayilearned #csharp
In another episode of Adventures with Entity Framework while migrating a legacy app…
Entity Framework Core only populated a child entity on one item in a result. To honor the 20-minute rule, and for my future self, here’s what I found:
TL;DR: You don’t need the WithOne() and HasForeignKey() when configuring the relationship.
#1. Let’s create an optional one-to-one relationship.
Let’s create a Movie and an Award table.
USE Movies;
GO
CREATE TABLE Awards (
Id INT PRIMARY KEY IDENTITY(1,1),
Name NVARCHAR(100) NOT NULL
);
CREATE TABLE Movies (
Id INT PRIMARY KEY IDENTITY(1,1),
Name NVARCHAR(100) NOT NULL,
AwardId INT NULL /* <-- Optional. No FK here */
);
GO
Since the relationship is optional, the AwardId is nullable. This type dictates what JOIN Entity Framework Core uses.
Let’s configure the relationship using HasOne() and WithOne().
using Microsoft.EntityFrameworkCore;
namespace LookMaWhatEntityFrameworkDoes;
public class Award
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Movie
{
public int Id { get; set; }
public string Name { get; set; }
public int? AwardId { get; set; }
// ^^^
// Optional
public Award Award { get; set; }
}
public class MovieContext : DbContext
{
public MovieContext(DbContextOptions<MovieContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<Movie>()
.HasOne(m => m.Award)
.WithOne()
.HasForeignKey<Movie>(m => m.AwardId)
.OnDelete(DeleteBehavior.Restrict);
}
public DbSet<Movie> Movies { get; set; }
public DbSet<Award> Awards { get; set; }
}
To verify Copilot’s answer, I went through the official docs here.
#3. Retrieve movies and their awards
And now, let’s create an award, add two movies, and retrieve them to check their awards.
using Microsoft.EntityFrameworkCore;
namespace LookMaWhatEntityFrameworkDoes;
[TestClass]
public class MovieTests
{
[TestMethod]
public async Task AllAwardsPlease()
{
const string connectionString = $"Server=(localdb)\\MSSQLLocalDB;Database=Movies;Trusted_Connection=True;";
var options = new DbContextOptionsBuilder<MovieContext>()
.UseSqlServer(connectionString)
.LogTo(Console.WriteLine)
.Options;
// 1. Let's create an "Oscar"
using (var context = new MovieContext(options))
{
context.Awards.Add(new Award
{
Name = "Oscar"
});
context.SaveChanges();
}
// 2. Let's create two movies that have won an "Oscar"
using (var context = new MovieContext(options))
{
var oscar = await context.Awards.FirstOrDefaultAsync();
Assert.IsNotNull(oscar);
context.Movies.AddRange(
new Movie
{
Name = "Forrest Gump",
AwardId = oscar.Id
},
new Movie
{
Name = "Titanic",
AwardId = oscar.Id
}
);
context.SaveChanges();
}
// 3. Let's retrieve all movies, expecting to have an Award
using (var context = new MovieContext(options))
{
var movies = await context.Movies
// Imagine more filters here
.Include(m => m.Award)
// ^^^^^
// Yes, I'm including it here
.ToListAsync();
foreach (var movie in movies)
{
Assert.IsNotNull(movie);
Assert.IsNotNull(movie.Award);
// ^^^^^
// Assert.IsNotNull failed.
// Play sad trumpet sound.
}
}
}
}
Sorry for the foreach inside the Assert. That’s not a good idea. But I’m lazy and I’m taking too long writing this.
Yes, it fails. Play sad trumpet, please. The second movie’s award isn’t populated. Arrggg!
My fault!
#4. Ignore WithOne()
Since I’m setting an unidirectional relationship, one movie/one award/multiple movies, only configuring HasOne() is enough.
Using WithOne() was telling Entity Framework Core that one award could only belong to one movie. And that’s not the case here.
public class MovieContext : DbContext
{
public MovieContext(DbContextOptions<MovieContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Remove the entire configuration
// Or,
modelBuilder
.Entity<Movie>()
.HasOne(m => m.Award);
// ^^^^^
// Just this
}
public DbSet<Movie> Movies { get; set; }
public DbSet<Award> Awards { get; set; }
}
And since I’m following default naming conventions, I could even delete the configuration. Ahh, Cascade sets to null, which is fine here.
Yes, the right answer is to do nothing.
Et voilà!
For debugging and problem-solving tips, read Street-Smart Coding. Those two skills are more relevant now in the era of AI-assisted coding.
09 Mar 2026 #csharp #todayilearned
In another adventure with Blazor…
While migrating a legacy app, I had to “componentize” an HTML editor. It used Summernote, “a super simple WYSIWYG editor on Bootstrap”.
The fun part was learning JavaScript interop: calling JavaScript from .NET and viceversa.
After some Googling and sneaking into abandoned GitHub repos, here’s what I came up with:
The component
In Summernote.razor:
@using Microsoft.AspNetCore.Components.Sections
<HeadContent>
<link rel="stylesheet" href="css/summernote.css" />
</HeadContent>
<div id="@_id">@((MarkupString)Value)</div>
<SectionContent SectionName="scripts">
<script src="js/summernote.js" type="text/javascript"></script>
</SectionContent>
In Summernote.razor.cs:
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace MyCoolComponents.HtmlEditor;
public partial class Summernote : IAsyncDisposable
{
private readonly string _id = $"summernote_{Guid.NewGuid()}";
private IJSObjectReference? _module;
private DotNetObjectReference<Summernote>? _dotnetRef;
private bool _editorInitialized = false;
[Parameter]
public string Value { get; set; }
[Parameter]
public EventCallback<string> ValueChanged { get; set; }
[Inject]
public IJSRuntime JsRuntime { get; set; } = default!;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!_editorInitialized)
{
_dotnetRef = DotNetObjectReference.Create(this);
_module = await JsRuntime.InvokeAsync<IJSObjectReference>("import", "./PutYourPathHere/Summernote.razor.js");
await _module.InvokeVoidAsync("edit", _id, _dotnetRef, nameof(OnTextChange));
_editorInitialized = true;
}
}
[JSInvokable]
public async Task OnTextChange(string editorText)
{
Value = editorText;
await ValueChanged.InvokeAsync(editorText);
}
public async ValueTask DisposeAsync()
{
if (_module is not null)
{
await _module.DisposeAsync();
}
_dotnetRef?.Dispose();
}
}
Here’s where the magic happens.
After rendering the component, it calls a JavaScript function that initializes the Summernote editor. Then, it registers a callback that calls a .NET function every time the editor changes to update the component state.
Notice it stores content in a MarkupString but it binds as a string.
In Summernote.razor.js:
export function edit(id, dotnetRef, callback) {
let snid = '#' + id;
$(snid).summernote({
callbacks: {
onChange: function (contents, $editable) {
dotnetRef.invokeMethodAsync(callback, contents);
}
}
});
}
How to use it
And here’s a sample form using the editor:
@using MyCoolComponents.HtmlEditor
<EditForm Model="MyCoolRequest" OnValidSubmit="OnValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="row">
<div class="form-group col-sm-9">
<label for="content" class="form-label">Content</label>
<Summernote @bind-Value="Annotation.Content" />
@* ^^^^^ *@
@* Look, Ma! It works! *@
<ValidationMessage For="() => Annotation.Content" class="invalid-feedback" />
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</EditForm>
This piece of code is provided “as is”, without warranty of any kind…Blah, blah, blah. Use under your own risk. Steal it.
If this helped you, you’ll love Street-Smart Coding—30 proven lessons to help you level up your coding journey.