Skip to content

Settings.NullableShortHand

Simon Hughes edited this page Aug 30, 2026 · 2 revisions

Settings.NullableShortHand and Settings.NullableReverseNavigationProperties

Two small settings about nullability that are easy to confuse with each other and with Settings.AllowNullStrings.

Settings.NullableShortHand Settings.NullableReverseNavigationProperties
Type bool bool
Default true false
Affects How a nullable value type is spelled Whether a one-to-one reverse navigation is nullable
In Database.tt? Yes Yes

Settings.NullableShortHand

Pure syntax. true gives int?; false gives Nullable<int>.

Document.ReviewedByUserId is a nullable int.

true (default)

    // Document
    public class Document
    {
        public int DocumentId { get; set; } // DocumentId (Primary key)

        /// <summary>
        /// The title shown to users. Not the file name.
        /// </summary>
        public string Title { get; set; } // Title (length: 100)
        public byte[] RowVersion { get; set; } // RowVersion (length: 8)
        public int? ReviewedByUserId { get; set; } // ReviewedByUserId
    }

false

    // Document
    public class Document
    {
        public int DocumentId { get; set; } // DocumentId (Primary key)

        /// <summary>
        /// The title shown to users. Not the file name.
        /// </summary>
        public string Title { get; set; } // Title (length: 100)
        public byte[] RowVersion { get; set; } // RowVersion (length: 8)
        public System.Nullable<int> ReviewedByUserId { get; set; } // ReviewedByUserId
    }

The two are the same type. The compiler treats int? as an alias for Nullable<int>, so this changes nothing but readability.

Leave it true. int? is idiomatic C# and has been since 2005. false exists for code style rules that demand explicit types, and for generators feeding tools that cannot parse the shorthand.

Settings.NullableReverseNavigationProperties

A modelling decision, not a syntax one.

In a one-to-one relationship the generator has to decide whether the parent's reference to the child may be null. Person has one Passport - but does every person have one?

false (the default) generates public Passport Passport { get; set; }, saying the child always exists. true generates public Passport? Passport { get; set; }, saying it might not.

true is usually the more honest answer: a one-to-one is normally optional on the parent end, because the child row holds the foreign key and can simply be absent.

It only affects one-to-one relationships. A one-to-many parent gets a collection, which is empty rather than null, and a child's reference to its parent follows the foreign key's own nullability.

Which of the three do I want?

I want Setting
int? rather than Nullable<int> NullableShortHand = true
string? for nullable string columns, and #nullable enable AllowNullStrings = true
Passport? on the parent of a one-to-one NullableReverseNavigationProperties = true

They are independent, and in a project with nullable reference types enabled you probably want all three.

Gotchas

NullableReverseNavigationProperties = true emits ? on a reference type, which is a compiler error in a project that has not enabled nullable reference types. Turn on Settings.AllowNullStrings alongside it - that is what writes #nullable enable into the generated file.

NullableShortHand has no effect on reference types. string has no shorthand to choose.

Neither changes the database mapping. IsRequired(false) in the configuration comes from the column's own nullability, whatever these are set to.

Both are all-or-nothing. For per-relationship control, use Settings.UpdateColumn and assign column.PropertyType.

See also

Clone this wiki locally