OData / OData/ModelBuilder

ModelBuilder throws exception during registration of key property of nullable enum type

Open
#36 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C#
Stars
22
Forks
24
PR merge metrics
No merged PRs in 30d

Description

The ODataConventionalModelBuilder throws an exception durng registration of entities with a key property that is of a nullable enum type:
System.ArgumentException: Type provided must be an Enum. (Parameter 'enumType')

Although key properties are never nullable in the created model, it should be possible to register key properties of a nullable enum type since there is no error for key properties of a nullable primitve type like int?.

Assemblies affected

OData ModelBuilder 1.0.9

Reproduce steps
  1. Create a new .Net 6 project
  2. Have an entity with a property of a nullable enum type
  3. Create an ODataConventionalModelBuilder instance
  4. Register the entity type
  5. Create the EdmModel

Example code:

using Microsoft.OData.ModelBuilder;
using System.ComponentModel.DataAnnotations;

var builder = new ODataConventionModelBuilder();
builder.EnableLowerCamelCase();

builder.EntityType<Customer>();
var model = builder.GetEdmModel();

enum Classification
{
    None,
    Test
}

class Customer
{
    [Key]
    public Classification? Classification { get; set; }
}
Expected result

The model builder would successfully create a model with a Customer entity that has a key property of type Classification.
Since it is a key property, it would be marked as non-nullable in the created model.

Actual result

When creating the EdmModel the following exception occurs:

Unhandled exception. System.ArgumentException: Type provided must be an Enum. (Parameter 'enumType')
   at System.RuntimeType.GetEnumUnderlyingType()
   at System.Enum.GetUnderlyingType(Type enumType)
   at Microsoft.OData.ModelBuilder.EnumTypeConfiguration..ctor(ODataModelBuilder builder, Type clrType)
   at Microsoft.OData.ModelBuilder.ODataModelBuilder.AddEnumType(Type clrType)
   at Microsoft.OData.ModelBuilder.ODataConventionModelBuilder.AddEnumType(Type type)
   at Microsoft.OData.ModelBuilder.EntityTypeConfiguration.HasKey(PropertyInfo keyProperty)
   at Microsoft.OData.ModelBuilder.Conventions.Attributes.KeyAttributeEdmPropertyConvention.Apply(StructuralPropertyConfiguration edmProperty, StructuralTypeConfiguration structuralTypeConfiguration, Attribute attribute, ODataConventionModelBuilder model)
   at Microsoft.OData.ModelBuilder.Conventions.Attributes.AttributeEdmPropertyConvention`1.Apply(TPropertyConfiguration edmProperty, StructuralTypeConfiguration structuralTypeConfiguration, ODataConventionModelBuilder model)
   at Microsoft.OData.ModelBuilder.Conventions.Attributes.AttributeEdmPropertyConvention`1.Apply(PropertyConfiguration edmProperty, StructuralTypeConfiguration structuralTypeConfiguration, ODataConventionModelBuilder model)
   at Microsoft.OData.ModelBuilder.ODataConventionModelBuilder.ApplyPropertyConvention(IEdmPropertyConvention propertyConvention, StructuralTypeConfiguration edmTypeConfiguration)
   at Microsoft.OData.ModelBuilder.ODataConventionModelBuilder.ApplyTypeAndPropertyConventions(StructuralTypeConfiguration edmTypeConfiguration)
   at Microsoft.OData.ModelBuilder.ODataConventionModelBuilder.MapTypes()
   at Microsoft.OData.ModelBuilder.ODataConventionModelBuilder.GetEdmModel()
   at Program.<Main>$(String[] args) in C:\Temp\Example\Program.cs:line 8
Additional detail
  • The same exception is thrown if the property is manually registered as a key on the entity type with the HasKey-method.
  • Properties of a nullable enum type that are no key can be registered on a entity type.
  • The registration of key properties of a nullable primitive type like int? are successfull. The model contains a key property of the primitive type that is marked as non-nullable since it is a key.
  • After a first look into the code: There might be missing a call to TypeHelper.GetUnderlyingType for the case of an enum type in the HasKey-method which is used in other code parts of the project.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at EntityTypeConfiguration.HasKey and compare its enum handling with the TypeHelper.GetUnderlyingType usage mentioned in the issue. Reproduce the failure with the provided nullable-enum Customer example, then verify that GetEdmModel creates a Customer key property successfully and marks it non-nullable.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.