Skip to content

Settings.AllowNullStrings

Simon Hughes edited this page Aug 30, 2026 · 1 revision

Settings.AllowNullStrings

Makes the generated code nullable-aware: a nullable database column becomes string?, and a non-nullable one gets = null!.

Type bool
Default false
Applies to EF 6 and EF Core
Databases All
In Database.tt? Yes

What it does

C# 8 introduced nullable reference types: with the feature on, string means "never null" and string? means "may be null", and the compiler warns when you get it wrong.

By default the generator ignores all that and declares every string as string, which is a lie for any nullable column and produces warnings in a project that has nullable reference types enabled.

Turning this on makes the generator tell the truth:

  • #nullable enable is written at the top of each generated file, so the setting works even if your project has not opted in globally.
  • A nullable column becomes string?.
  • A non-nullable column stays string and is initialised = null!, which tells the compiler "EF will populate this, stop warning me".
  • Required navigation properties get = null! for the same reason.

Example

Product.ProductName is NOT NULL; Notes and the computed DisplayLabel are nullable.

Settings.AllowNullStrings = false (default)

    // Product
    public class Product
    {
        public int ProductId { get; set; } // ProductId (Primary key)
        public string ProductName { get; set; } // ProductName (length: 100)
        public decimal UnitPrice { get; set; } // UnitPrice
        public string Notes { get; set; } // Notes
        public int CategoryId { get; set; } // CategoryId
        public string DisplayLabel { get; private set; } // DisplayLabel (length: 150)

        // Foreign keys

        /// <summary>
        /// Parent Category pointed by [Product].([CategoryId]) (FK_Product_Category)
        /// </summary>
        public Category Category { get; set; } // FK_Product_Category

        public Product()
        {
            UnitPrice = 0m;
        }
    }

Settings.AllowNullStrings = true

    // Product
    public class Product
    {
        public int ProductId { get; set; } // ProductId (Primary key)
        public string ProductName { get; set; } = null!; // ProductName (length: 100)
        public decimal UnitPrice { get; set; } // UnitPrice
        public string? Notes { get; set; } // Notes
        public int CategoryId { get; set; } // CategoryId
        public string? DisplayLabel { get; private set; } // DisplayLabel (length: 150)

        // Foreign keys

        /// <summary>
        /// Parent Category pointed by [Product].([CategoryId]) (FK_Product_Category)
        /// </summary>
        public Category Category { get; set; } = null!; // FK_Product_Category

        public Product()
        {
            UnitPrice = 0m;
        }
    }

Three changes: Notes and DisplayLabel became string?, and ProductName and the Category navigation property gained = null!.

When to use it

Turn it on if your project has <Nullable>enable</Nullable>. Otherwise the generated file produces a warning for every non-nullable string property - "Non-nullable property must contain a non-null value when exiting constructor" - and those warnings drown the ones you care about.

Leave it off for a project that has not adopted nullable reference types. string? in a file whose project has the feature disabled is a compiler error, not a warning.

Gotchas

= null! is a promise, not a check. It says "trust me, this is populated". It is true when EF materialises the entity and false when you write new Product() yourself, where ProductName really is null despite its type. That is the standard EF Core compromise, not something this generator invents.

It changes value types too, not just strings, despite the name. Nullable columns of every type follow the same rule, though int? was already how a nullable int was generated.

It interacts with Settings.NullableShortHand. NullableShortHand chooses between int? and Nullable<int>; this chooses whether reference types participate at all.

The generated file opts itself in. #nullable enable at the top means the file is nullable-aware even in a project that is not. That is deliberate - it keeps the generated code consistent - but it can surprise you when the generated file is the only one with the feature on.

Settings.NullableReverseNavigationProperties is separate. This setting handles required navigation properties with = null!; that one decides whether one-to-one reverse navigations are declared nullable.

See also

Clone this wiki locally