Search code examples
c#entity-framework-coreodataedmxnullable-reference-types

OData metadata not generating Nullable facet when using nullable reference types


I have a simple C# data model that I am using with Entity Framework Core and OData that is being built with Nullable Reference Types "enable".

 public record Country
{
    [Key]
    [DisplayName("ISO Code")]
    [MaxLength(2)]
    [MinLength(2)]
    public string ISOCode { get; init; } = string.Empty;

    public string Name { get; init; } = string.Empty;
}

When building the EF Core and SQL database the property Name is created NOT NULL:

CREATE TABLE [dbo].[Country] (
[ISOCode] NVARCHAR (2)   NOT NULL,
[Name]    NVARCHAR (MAX) NOT NULL,
CONSTRAINT [PK_Country] PRIMARY KEY CLUSTERED ([ISOCode] ASC));

However, when I build the OData endpoint there is no NULLABLE facet:

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
    <edmx:DataServices>
        <Schema Namespace="DiveShopService.Models" xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <EntityType Name="Country">
                <Key>
                    <PropertyRef Name="ISOCode" />
                </Key>
                <Property Name="ISOCode" Type="Edm.String" Nullable="false" MaxLength="2" />
                <Property Name="Name" Type="Edm.String" />
            </EntityType>
        </Schema>
        <Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
            <EntityContainer Name="Container">
                <EntitySet Name="Countries" EntityType="DiveShopService.Models.Country" />
            </EntityContainer>
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>

It should be <Property Name="Name" Type="Edm.String" Nullable="false" />

Is there some configuration option to cause OData to understand Nullable Reference Types?

Visual Studio 16.8.4 Microsoft.EntityFrameworkCore v5.0.2 Microsoft.AspNetCore.OData v8.0.0-preview3 .NET 5.0


Solution

  • I did some investigation into the differences between EF Core and OData when building a model for this simple type.

    Note for clarity: The problem is more precisely with NonNullable reference (and navigation) types.

    It turns out that the OData EDM builder does not explicitly handle this case and as Sam commented, that is "By Design". If you want to share common source models between EF and OData you should use the [Required] attribute. Or modify the model using the fluent API.

    Update: Fixed in Microsoft.OData.ModelBuilder