OData / OData/AspNetCoreOData

How do I define custom/dynamic OData columns/fields/properties?

Open
#517 8 comments 2 reactions 1 assignee View on GitHub

@xuzhg is already working on this.

Since Mar 15, 2022.

Dominant language
C#
Stars
505
Forks
186
PR merge metrics
No merged PRs in 30d

Description

I realize that there is a sample here for creating 100% dynamic models. However, in our case we have an existing model that we are happy with, but we want to add custom fields to it.

In other words, we want an OData model with entities that have some fixed columns/properties and some dynamically-generated columns/properties that come from the database, like this:

public class ODataEntity
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; } = "";

    // From the perspective of Power BI, this should produce a series of additional columns 
    // (the columns are the same on all instances, but the schema can change at any time)
    public Dictionary<string, object> CustomFields { get; set; }
}

To my tremendous surprise, the key-value pairs in CustomFields become properties in the JSON output (i.e. there is no CustomFields column; its contents are inserted into the parent object). However, the custom fields are not recognized by Power BI:

image

I assume that this is because there is no metadata for the custom fields in https://.../odata/$metadata. So my question is:

  1. How can I modify the following code so that the custom columns are included in the IEdmModel?

    static IEdmModel GetEdmModel(params CustomFieldDef[] customFields)
    {
        var builder = new ODataConventionModelBuilder() {
            Namespace = "Namespace",
            ContainerName = "Container", // no idea what this is for
        };
        builder.EntitySet<ODataEntity>("objects");
    
        return builder.GetEdmModel();
    }
    
    public class CustomFieldDef {
        public string FieldName;
        public Type Type;
    }
    
  2. How can I modify the following startup code so that the IEdmModel is regenerated every time https://.../odata/$metadata is accessed?

    IMvcBuilder mvc = builder.Services.AddControllers();
    
    mvc.AddOData(opt => opt.AddRouteComponents("odata", GetEdmModel())
       .Select().Filter().OrderBy().Count().Expand().SkipToken());
    

Edit: mirrored on SO

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.