Search code examples
odataasp.net-web-apiasp.net-web-api2

How to build EDM model for OData Web API in runtime?


I have a case when my entities that I need to expose through OData are completely dynamic (e.g., user can configure which fields he wants to expose). Query results from repository are stored in special generic class that has a dictionary for actual data (FieldName/Value), so CLR type is one for all. I have complete knowledge about the entity (entity name, entity fields and their types).

Because of that I can't build EDM model in design-time using ODataModelBuilder methods like Entity, EntitySet or HasKey(), Property() from EntityTypeConfiguration.

Is it possible to build EDM model from scratch? ODataModelBuilder uses EntityTypeConfiguration, but it depends on CLR type of entity. Basically I need to declare several entity types with one CLR type for all of them.

Please advise.


Solution

  • Ok, so I've figured out an answer to this problem.

    I've written my own OData model builder that uses types from Microsoft.Data.Edm.Library namespace (EdmModel, EdmEntityType and so on).

    Example:

    public IEdmModel GetEdmModel()
    {
        EdmModel model = new EdmModel();
    
        EdmEntityContainer container = new EdmEntityContainer(Namespace, "DefaultContainer");
        model.AddElement(container);
        model.SetIsDefaultEntityContainer(container, isDefaultContainer: true);
    
        EdmEntityType edmType = new EdmEntityType(Namespace, "Foo");
        EdmStructuralProperty idProp = edmType.AddStructuralProperty("Id", EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.Int32), false);
        edmType.AddKeys(idProp);
    
        сontainer.AddEntitySet("MyEntitySet", edmType);
    
        model.SetDataServiceVersion(new Version(3, 0, 0, 0));
        model.SetMaxDataServiceVersion(new Version(3, 0, 0, 0));
    
        return model;
    }