Required and Optional Properties

A property is considered optional if it is valid for it to contain null. If null is not a valid value to be assigned to a property then it is considered to be a required property.

When mapping to a relational database schema, required properties are created as non-nullable columns, and optional properties are created as nullable columns.

Conventions

By convention, a property whose .NET type can contain null will be configured as optional, whereas properties whose .NET type cannot contain null will be configured as required. For example, all properties with .NET value types (int, decimal, bool, etc.) are configured as required, and all properties with nullable .NET value types (int?, decimal?, bool?, etc.) are configured as optional.

C# 8 introduced a new feature called nullable reference types, which allows reference types to be annotated, indicating whether it is valid for them to contain null or not. This feature is disabled by default, and if enabled, it modifies EF Core's behavior in the following way:

  • If nullable reference types are disabled (the default), all properties with .NET reference types are configured as optional by convention (e.g. string).
  • If nullable reference types are enabled, properties will be configured based on the C# nullability of their .NET type: string? will be configured as optional, whereas string will be configured as required.

The following example shows an entity type with required and optional properties, with the nullable reference feature disabled (the default) and enabled:

public class CustomerWithoutNullableReferenceTypes
{
    public int Id { get; set; }
    [Required]                               // Data annotations needed to configure as required
    public string FirstName { get; set; }    
    [Required]
    public string LastName { get; set; }     // Data annotations needed to configure as required
    public string MiddleName { get; set; }   // Optional by convention
}

Using nullable reference types is recommended since it flows the nullability expressed in C# code to EF Core's model and to the database, and obviates the use of the Fluent API or Data Annotations to express the same concept twice.

Note

Exercise caution when enabling nullable reference types on an existing project: reference type properties which were previously configured as optional will now be configured as required, unless they are explicitly annotated to be nullable. When managing a relational database schema, this may cause migrations to be generated which alter the database column's nullability.

For more information on nullable reference types and how to use them with EF Core, see the dedicated documentation page for this feature.

Configuration

A property that would be optional by convention can be configured to be required as follows:

using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;

namespace EFModeling.DataAnnotations.Required
{
    class MyContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
    }

    public class Blog
    {
        public int BlogId { get; set; }
        [Required]
        public string Url { get; set; }
    }
}