ModelBuilder icon indicating copy to clipboard operation
ModelBuilder copied to clipboard

Question: Vocabulary annotations for contained entity sets?

Open maximpashuk opened this issue 6 years ago • 3 comments

Interface IEdmEntitySet include interface IEdmVocabularyAnnotatable, so I can set, for example, optimistic concurrency properties for top-level entity set.

BUT, interface IEdmContainedEntitySet not include IEdmVocabularyAnnotatable, so I can't set optimistic concurrency properties for non-top level entity set.

Probably I am missing something, but element from top-level EntitySet and it child from selecondlevel ContainedEntitySet both can have concurrency properties.

Can somebody explain why contained entity set so restricted that them cannot be annotated?

maximpashuk avatar Oct 08 '18 12:10 maximpashuk

FYI: I have some issue search, and probably my question has some relations with issue https://github.com/OData/WebApi/issues/472

maximpashuk avatar Oct 10 '18 05:10 maximpashuk

@mikepizzo please follow up this issue with OASIS TC. Thanks.

biaol-odata avatar Oct 10 '18 20:10 biaol-odata

Recently updated my project to OData 8.0.8 and issue is still present in 2022.

Reproduce: just add contained entity with concurrency token (in my case user.ContainsMany(userProfiles), userProfile has concurrencyToken declared)

Later if I trying to patch userProfile and set If-Match header in my http request, but in ODataQueryOptions.IfMatch I can't see concurrencyToken, because it is not annotated correctly in edm model.

As a workaround I use following snippet, hope you understand my domain context

    public static IEdmModel AddUserProfileConcurrency(this IEdmModel model)
    {
        var users = model.EntityContainer.FindEntitySet("users");
        var user = users.EntityType();
        var profiles = (IEdmNavigationProperty) user.FindProperty("profiles");
        var profilesTarget = users.FindNavigationTarget(profiles);
        var profile = profilesTarget.EntityType();
        var concurrencyProperty = (IEdmStructuralProperty) profile.FindProperty("concurrency");

        var concurrencyProperties = model.GetAnnotationValue<ConcurrencyPropertiesAnnotation>(model) ??
                                    new ConcurrencyPropertiesAnnotation();
        concurrencyProperties[profilesTarget] = new[] {concurrencyProperty};

        model.SetAnnotationValue(model, concurrencyProperties);

        return model;
    }

If I just set .IsConcurrencyToken() on concurrency property, this simply doesn't work, ETagMessageHandler not worked correcly for contained entity sets.

@xuzhg please take a look, probably this issue should be transferred to https://github.com/OData/ModelBuilder repo, I not sure

maximpashuk avatar Mar 05 '22 12:03 maximpashuk