OData / OData/ModelBuilder

Annotations for basetype properties only added to last type added in .Net 7

Open
#34 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

In .Net 7 annotations for basetype properties are only added to the last type.

Assemblies affected

Microsoft.OData.ModelBuilder 1.0.9

Reproduce steps

This program throws InvalidOperationException, while it runs fine when TargetFramework is net6.0.

ConsoleApp.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.OData.ModelBuilder" Version="1.0.9" />
  </ItemGroup>
</Project>

Program.cs

using Microsoft.OData.Edm;
using Microsoft.OData.ModelBuilder;

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

builder.EntityType<Derived1>();
builder.EntityType<Derived2>();

var model = builder.GetEdmModel();

var entityType1 = model.FindType("Default.Derived1") as EdmEntityType;
var idProperty1 = entityType1!.FindProperty("id");
var annotation1 = model.GetAnnotationValue<ClrPropertyInfoAnnotation>(idProperty1);

var entityType2 = model.FindType("Default.Derived2") as EdmEntityType;
var idProperty2 = entityType2!.FindProperty("id");
var annotation2 = model.GetAnnotationValue<ClrPropertyInfoAnnotation>(idProperty2);

if (annotation1 is null || annotation2 is null)
{
    throw new InvalidOperationException();
}

public abstract class BaseEntity
{
    public Guid Id { get; set; }
}

public sealed class Derived1 : BaseEntity { }
public sealed class Derived2 : BaseEntity { }
Expected result

Annotations for basetype properties should be added to both derived types.

Actual result

Annotations for basetype properties are only added to the last type added.

Additional detail

Stepping through the code shows that EdmTypeMap.EdmProperties has only 1 PropertyInfo item while in .Net 6 there are 2.
image

I have found 2 workarounds, either:

  1. Add basetype: builder.EntityType<BaseEntity>();
  2. Change baseclass to an interface

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 with the Program.cs reproduction and its ConsoleApp.csproj targeting net7.0, then trace how EdmTypeMap.EdmProperties is populated when GetEdmModel processes Derived1 and Derived2. Run the reproduction against the affected package and compare with net6.0; done means both derived id properties have non-null ClrPropertyInfoAnnotation values.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
api, backend-api-design
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.