Skip to content

Change EdmModel at runtime for the same route #1500

@reneduesmann

Description

@reneduesmann

Hey,

Versions that i use:
Microsoft.AspNetCore.OData Version: 9.3.2
.NET 9 Version

I´m coming from the dynamics 365 crm universe and build at the moment my own crm.
I like the functionality of the dynamics 365 crm that i can CRUD tables/columns and relationships.
At the moment i get all entites from my DbContext and add those to the ODataConventionModelBuilder.
Here is the code for it:

static ODataConventionModelBuilder GetODataConventionModelBuilder()
{
    ODataConventionModelBuilder oDataConventionModelBuilder = new();
    Type contextType = typeof(ApplicationDbContext);

    IEnumerable<PropertyInfo> dbSetProperties = contextType
        .GetProperties(BindingFlags.Public | BindingFlags.Instance)
        .Where(x => x.PropertyType.IsGenericType && x.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>));

    foreach (PropertyInfo dbSetProperty in dbSetProperties)
    {
        Type entityType = dbSetProperty.PropertyType.GetGenericArguments()[0];
        string setName = dbSetProperty.Name;

        EntityTypeConfiguration entityTypeConfig = oDataConventionModelBuilder.AddEntityType(entityType);

        PropertyInfo idProperty = GetPrimaryKeyFromEntity(entityType);

        if(idProperty is not null)
        {
            entityTypeConfig.HasKey(idProperty);
        }

        oDataConventionModelBuilder.AddEntitySet(setName, entityTypeConfig);
    }

    return oDataConventionModelBuilder;
}

This works well, but as i said, users can modify the database from the ui and i want to show these changes in the odata endpoint as well.
And for my understanding i need to modify the current EdmModel for my static odata route (the route and version shouldn't change, the url should be always the same).
As an example the user creates a table "Book", the model/odata should display the table too after creating it.
The informations about the new tables, columns and so on are stored in different tables.
In theory i would retrieve the informations about the changes and create a new EdmComplexType like in this documentation.

This is my program.cs file:

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

ODataConventionModelBuilder oDataConventionModelBuilder = GetODataConventionModelBuilder();

Dictionary<Type, string> entitySetNames = oDataConventionModelBuilder
    .EntitySets
    .ToDictionary(es => es.EntityType.ClrType, es => es.Name);

builder.Services
    .AddControllers()
    .ConfigureApplicationPartManager(apm =>
    {
        apm.FeatureProviders.Add(new DynamicODataControllerFeatureProvider(entitySetNames));
    })
    .AddOData(options =>
    {
        options.EnableQueryFeatures();
        options.AddRouteComponents("api", oDataConventionModelBuilder.GetEdmModel());
    });

builder.Services.AddLogging(configuration =>
{
    configuration.AddConsole();
});

WebApplication app = builder.Build();

app.UseHttpsRedirection();

app.UseRouting();

app.UseODataRouteDebug();

app.UseAuthorization();

app.MapControllers();

app.Run();

But what are the next steps?
I don't find anything to that topic (only #1351 but it didn't helped me out)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions