TIL: How To Ignore Unmapped Fields in the Destination Type With AutoMapper

Another day working with AutoMapper, another day with an edge case.

Let’s say we have class CreateMovieRequest with three properties: name, release year, and another property I don’t want to map, for some reason. And a destination class, Movie, with more properties apart from those three and names using a prefix.

Simply trying to use CreateMap<CreateMovieRequest, Movie>() won’t work. AutoMapper will warn you about unmapped properties in the destination type. “Unmapped members were found. Review the types and members below.”

Here’s how to map two classes ignoring the unmapped properties in the destination type and with prefixes:

using AutoMapper;

namespace TestProject1;

[TestClass]
public class IHateYouWilWheaton
{
    public class CreateMovieRequest
    {
        public string Name { get; set; }
        public int ReleaseYear { get; set; }
        public string IDontWantThisOneMapped { get; set; }
    }

    public class Movie
    {
        // These two aren't mapped from the source
        public int Id { get; set; }
        public int DurationInMinutes { get; set; }
        // These two have the 'Movie' prefix
        public string MovieName { get; set; }
        public int MovieReleaseYear { get; set; }
    }

    [TestMethod]
    public void IgnoringNotMappedProps()
    {
        var config = new MapperConfiguration(cfg =>
        {
            // Let's keep it here, shall we?
            cfg.RecognizeDestinationPrefixes("Movie");
            //  ^^^^^
            // To avoid explicitly mapping the fields because of the prefix

            // Before:
            // cfg.CreateMap<CreateMovieRequest, Movie>();
            //     ^^^^^
            // AutoMapper.AutoMapperConfigurationException: 
            // Unmapped members were found. Review the types and members below.
            // ...
            // Unmapped properties:
            // Id
            // MovieName
            // DurationInMinutes
            //
            //
            // After:
            cfg.CreateMap<CreateMovieRequest, Movie>(MemberList.Source)
                //                                   ^^^^^
                // To validate unmapped properties on the source type
                // Possible options: Source, Destination, and None			
                .ForSourceMember(src => src.IDontWantThisOneMapped, opt => opt.DoNotValidate());
                // ^^^^^
                // Since I don't want this one mapped for some reason
        });
        config.AssertConfigurationIsValid();

        var source = new CreateMovieRequest
        {
            Name = "Space Odyssey",
            ReleaseYear = 1968,
            IDontWantThisOneMapped = "Ok, if you say so"
        };

        var mapper = config.CreateMapper();
        var destination = mapper.Map<Movie>(source);

        Assert.AreEqual(destination.MovieName, source.Name);
        Assert.AreEqual(destination.MovieReleaseYear, source.ReleaseYear);
    }
}

The trick for prefixes is RecognizeDestinationPrefixes() and the one for warnings is passing any of Source, Destination, or None as a parameter to Map().

And to ignore an “incoming” property, ForSourceMember(), with DoNotValidate().

Et voilà!

You Don't Need a Published Book to Call Yourself a Writer

Is it a best-selling book? A Pulitzer-winning novel? A large newsletter? More than 1,000 articles published anywhere online?

When can we call ourselves “writers”?

I have to confess I’ve been reluctant to use “digital writer” or “technical writer” or “writer” as a title anywhere online, even though I’ve been writing in my small corner of the Internet since 2018.

But recently, watching this interview with Devon Eriksen on YouTube, I changed my mind about using the title “writer.” He says:

If you’ve written and you’ve gotten paid for it. You’re a writer.

After hearing that, I wasn’t afraid to change my tagline on social media and here on my blog.

Definitely, someone has asked me to write something and paid me for that. That was by pure accident or luck, thanks to sharing the tutorials I write here on my blog. That’s how I made my first internet money.

You don’t need to publish a book. Well, publishing a book isn’t that hard these days. James Altucher has a strategy to publish a book in 30 days.

You don’t need to write and publish a book to call yourself a writer. Find one person that will pay to write and start calling yourself a “writer.” I’m a writer. And you?

TIL: Configure Default Values for Nullable Columns With Default Constraints in EntityFramework Core

TL;DR: For nullable columns with default constraints, you have to tell EntityFramework the default value of the mapping property via C#. Otherwise, when you create a new record, it will have NULL instead of the default value in the database. You’re welcome! Bye!

Let’s create a dummy table with one nullable column but with a defualt constraint

Let’s create a new Movies database with one table called Movies, with an Id, a name, and a director name as optional, but with a default value. Like this,

CREATE DATABASE Movies;
GO
USE Movies;
GO
CREATE TABLE Movies (
    Id INT PRIMARY KEY IDENTITY(1,1),
    Name NVARCHAR(100) NOT NULL,
    DirectorName NVARCHAR(100) DEFAULT 'ThisIsADefaultValue'
);
GO

Let’s create a new record (without the nullable column) and read it back

Now to prove a point, let’s use EntityFramework Core to insert a new movie without passing a director name and read it back.

What will be the value of DirectorName once we read it back? Null? The value inside the default constraint? Make your bets!

Here we go,

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace TestProject1;

[TestClass]
public class EntityFrameworkAndDefaults
{
    [TestMethod]
    public void TestInsertAndReadMovie()
    {
        const string connectionString = $"Server=(localdb)\\MSSQLLocalDB;Database=Movies;Trusted_Connection=True;";

        var dbContextOptions = new DbContextOptionsBuilder<MoviesContext>()
                .UseSqlServer(connectionString)
                .Options;

        using (var context = new MoviesContext(dbContextOptions))
        {
            var inception = new Movie
            {
                Name = "Inception"
                // No director name here...
                // ^^^^^
            };
            context.Movies.Add(inception);
            context.SaveChanges();
        }

        using (var context = new MoviesContext(dbContextOptions))
        {
            var movie = context.Movies.FirstOrDefault(m => m.Name == "Inception");

            Assert.IsNotNull(movie);
            Assert.AreEqual("ThisIsADefaultValue", movie.DirectorName);
            //     ^^^^^^^^
            //     Assert.AreEqual failed. Expected:<ThisIsADefaultValue>. Actual:<(null)>. 
            //
            // Whaaaaat!
        }
    }
}

public class MoviesContext : DbContext
{
    public DbSet<Movie> Movies { get; set; }

    public MoviesContext(DbContextOptions<MoviesContext> options)
        : base(options)
    {
    }
}

public class Movie
{
    public int Id { get; set; }
    public required string Name { get; set; }
    public string? DirectorName { get; set; }
}

Ok, to my surprise that test fails. movie.DirectorName isn’t "ThisIsADefaultValue". It’s null.

I was expecting to see the value from the default constraint in the database. But, no. Wah, wah, wah, Wahhhhhhh…

Here you have it EntityFramework. Can I get my default value now?

We have to tell EntityFramework Core the default value of our column, like this,

public class MoviesContext : DbContext
{
    public DbSet<Movie> Movies { get; set; }

    public MoviesContext(DbContextOptions<MoviesContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // For simplicity, let keep it here...
        modelBuilder.Entity<Movie>(entity =>
        {
            entity
                .Property(e => e.DirectorName)
                .HasDefaultValueSql("ThisIsADefaultValue");
                // ^^^^^
                // Here you have it EntityFramework Core
                // Can I get my default value now?
        });
    }
}

This behavior only adds up to my love and hate relationship with EntityFramework Core.

Et voilà!

Starting out or already on the coding journey? Join my free 7-day email course to refactor your software engineering career now – I distill 10+ years of career lessons into 7 short emails.

AI Is The Future And We, Coders, Have To Adapt

AI is here to stay. We can’t deny that.

One day, will AI become self-conscious and try to exterminate us all? Who knows. That’s another discussion.

But we, as coders, have to adapt, as we always have, and adopt AI.

Today, I had a conversation with a group of ex-coworkers. One of the members shared he was asked to finish almost an entire working app as part of a take-home coding challenge for an interview process at a startup. He was given only 5 hours. We all agreed that 5 hours wasn’t enough.

Someone else said he should have used AI. But he refused.

Maybe the intention behind that take-home challenge was to use AI and come up with a decent working prototype quickly. Who knows? Companies aren’t that clear with their interview process. And hiring is broken.

But we can’t refuse to use AI.

AI is here to make us more efficient. What used to take days, now it only takes hours or minutes. By pressing a button, we compile thousands of source files in just seconds. Refusing to use AI is like refusing to use calculators or spreadsheets for accounting. It’s like refusing to travel by plane or drive a car.

In our fast-paced world, where efficiency and productivity are rewarded, AI is a game-changer.

We can’t pretend to keep using punch cards and computers that fill an entire room. AI is the future. And we have to adapt. Coding in 2034 will change. But, one thing is certain: we can’t use AI to replace our thinking. We should be the pilots, and AI as our copilot.

Refactor your coding career with my free 7-day email course. In just 7 emails, you’ll get 10+ years of career lessons to avoid costly career mistakes.

Writing Isn't Something That Only Writers Do

What’s the first thing that comes to your mind when you hear “writer”?

Probably it’s a starving artist isolated in a cabin, in the middle of nowhere, typing the next award-winning best-selling novel on an old typewriter, holding a cigar.

The truth is you don’t have to be a “writer” to write.

That’s the main lesson from “Writing to Learn” by William Zinsser. Here are five lessons I learned from that book—in five quotes:

1. “Contrary to general belief, writing isn’t something that only “writers” do; writing is a basic skill for getting through life.”

A CV, a cover letter, an email for a client, a request for time off, and a resignation email. What do they all have in common? Writing!

And that’s only thinking of an employee in a full-time job. But writing is everywhere else.

2. “Writing organizes and clarifies our thoughts”

If you want to check if you know a subject well enough, try to explain it and even better, write about it.

When you write you need a message, a chain of thoughts, and a reader persona. You need the right words and the right amount of them. The act of writing solidifies your understanding and shows you your gaps.

Writing is thinking.

3. “Writing is learned mainly by imitation”

Writers are readers too.

And noticing your behavior as a reader is your cheat code to better writing. Notice your favorite passages from the books you read, the posts you read until the end, the social media posts that make you stop scrolling. How did they grab your attention? What title did they use? Why did they make you read?

If you need a writing mentor, hand-copy your favorite writer and find patterns in their writing.

4. “The hard part isn’t the writing, the hard part is the thinking”

There’s writing to share information and writing to discover what we want to say.

When you write to share information, you need to ask yourself, “what do I want to say?” And when you write to discover what to say, you’re free to leave questions without answers and to build up from an answer you don’t have yet.

Either type of writing makes you think clearly.

5. “Non-fiction writing should always have a point: it should leave the reader with a set of facts, or an idea, or a point of view, that he didn’t have when he started reading”

Can this benefit one person?

That’s the best guideline to decide what to write. If it can benefit one person, you can write lessons, stories, rants, mistakes, questions, and predictions… Anything!

If it can benefit one person, you’re safe to write. And that one person can be your past self.


You don’t need to be an expert to write. Who’s an expert anyway? You don’t need to be famous either. Share what you have learned. Share what you’re learning. Share what inspires you. You don’t need to be a writer for that. Write! Probably the next time you’re Googling something you’ll find your own writing.