3
votes

We were using WebApi OData v3 and had a couple ComplexType entities defined in the entity data model that contained EntitySet entities.

When moving to OData v4 and upon doing the modelBulder.GetEdmModel() step we get an InvalidOperationException "The complex type 'Foo' refers to the entity 'Bar' through the property 'Bar'."

I look at the spec and see a thing called an "abstract entity type" that is a type that holds entity types. I don't see that in the WebApi OData code so I hope that all I have to do is declare an EntityType that has no key and I get one.

No dice. Making my Foo type an EntityType (doing modelBuilder.AddEntityType(typeof(Foo)) instead of modelBuilder.AddComplexType(typeof(Foo))) gives an InvalidOperationException "The entity 'Foo' does not have a key defined".

Is there a entity-data-model clean way to use a ComplexType or an EntityType?

One clean but painful solution would be to make even more classes that are essentially my entities renamed and added to the model as ComplexType so that I can return the data as a complex type (I would include casting operators from the entity types to the matching complex types so they could be used interchangeably in client code). Obviously, I don't want to go through this pain for something that worked fine before upgrading to OData v4.

A much easier but non-clean way (and I have done this and it works) involves inserting an unused key into each now EntityType that used to be a ComplexType like this:

/// <summary>
/// Gets or sets the not used "key" property
/// </summary>
/// <remarks>
/// OData v4 seems to have broken the ability of a complex type to hold 
/// an entity type. In the spec, there is the notion of an abstract 
/// entity type - an entity type that does not have a key. But, it 
/// appears v4 doesn't support abstract entity types. Hence, this "key".
/// </remarks>
[Key]
public int NotUsed { get; set; }
1

1 Answers

1
votes

This is a part of the V4 protocol that hasn't been implemented by the ODataLib for OData V4 yet (thus Web API for OData V4 doesn't support defining such model as it's based on ODataLib and other core libraries). Please open a Github issue on https://github.com/odata/odata.net/issues to ask for it and help track it.