OData / ModelBuilder

A project to generate Edm (Entity Data Model) from CLR types
19 stars 19 forks source link

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

Open jr01 opened 1 year ago

jr01 commented 1 year ago

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