Search code examples
c#entity-framework.net-coremigrationnullable-reference-types

SQLite Error 19: 'NOT NULL constraint failed' - Are strings nullable by default in .NET6/C# 8?


I am having this issue after migrating my project from .NET 5 to .NET 6. I am using the latest version of SQLite as the database.

Visual Studio seems to be assuming that string is no longer nullable by default. Whenever Entity Framework tries to write to a field that is not a primary or foreign key I get the error SQLite Error 19: 'NOT NULL constraint failed. In .NET 5 I was not getting this error.

I also noticed that VS 2022 Intellisense has a green indicator line under each of the property names that cause this error. It states Non-nullable property must contain a non null-value when exiting constructor. Consider declaring the property as nullable.

Example of code the causes the error:

    [Table("ApplicationUser")]
    public class ApplicaitonUser : IdentityUser
    {
        // Inherited properties https://learn.microsoft.com/en-us/aspnet/core/security/authentication/customize-identity-model?view=aspnetcore-6.0
        [Key]
        public new int Id { get; set; } // every other property causes the SQLite 19 error
        
        [PersonalData]
        public string FirstName { get; set; }

        [PersonalData]
        public string MiddleName { get; set; }
        
        [PersonalData]
        public string LastName { get; set; }

        [PersonalData]
        public string PreferredName { get; set; }

        // Address Table Foreign Key relationship navigation property 
        [PersonalData]
        ICollection<UsAddress> UsAddresses { get; set; }


    }

Solution

  • Nullable Aware Context

    No, in .Net 6/C#8 Microsoft introduced "nullable aware context". When enabled, this context makes strings not-nullable by default. To be nullable then requires a nullable designation, like other types. This is useful for testing, etc... And is more consistent with a strongly typed framework.

    This feature can be turned on and off using the <nullable>enable</nullable or <nullable>disable</nullable> attribute in the Project file. Since the feature is disabled by default, the attribute can also be removed to disable it.

    Nullable contexts

      <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <Nullable>enable</Nullable>
      </PropertyGroup>
    

    In a nullable aware context:

    • A variable of a reference type T must be initialized with non-null, and may never be assigned a value that may be null.
    • A variable of a reference type T? may be initialized with null or assigned null, but is required to be checked against null before de-referencing.
    • A variable m of type T? is considered to be non-null when you apply the null-forgiving operator, as in m!.

    The distinctions between a non-nullable reference type T and a nullable reference type T? are enforced by the compiler's interpretation of the preceding rules. A variable of type T and a variable of type T? are represented by the same .NET type.

    Nullable reference types

    Examples:

    string notNullable = "Hello";
    string? nullable = default;
    notNullable = nullable!; // null forgiveness
    

    Additional information:

    Learn techniques to resolve nullable warnings

    Update a codebase with nullable reference types to improve null diagnostic warnings