Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core OData entity with private setters on properties

I have this entity:

    public int Id { get; private set; }
    public string Name { get; private set; }
    public Behavior Behavior { get; private set; }

    public Product(int id, string name, Behavior behavior)
    {
        Id = id;
        Name = name;
        Behavior = behavior;
    }

In startup method I'm registering the EdmModel :

        var builder = new ODataConventionModelBuilder();
        var entitySet = builder.EntitySet<Product>("Products");
        entitySet.EntityType.HasKey(x => x.Id);


        var model = builder.GetEdmModel();



        app.UseMvc(route =>
        {
            route.Select().Filter().Expand().OrderBy().Count().MaxTop(null);
            route.MapODataServiceRoute("odata", null, model);
            route.EnableDependencyInjection();
        }
        );

When I'm running my app, this exception occurs:

         InvalidOperationException: The entity 'Product' does not have a key 
         defined.

If I change private setter to public all is working. Also others properties with private setters are giving: ODataException Product does not contain property with name 'Name'. How can I solve it ?

like image 993
Nicu Besliu Avatar asked Aug 13 '18 09:08

Nicu Besliu


People also ask

How to build web APIs with OData support using ASP NET Core?

Sample: Build web APIs with OData support using ASP.NET Core 1 Register OData. Add the Microsoft.AspNetCore.OData NuGet package to the project. ... 2 Configure middleware. OData can perform sorting, filtering, querying related data, and more. ... 3 Update the controller. ... 4 Query resources using OData. ...

What are entity relations in OData v4?

Entity Relations in OData v4 Using ASP.NET Web API 2.2. Most data sets define relations between entities: Customers have orders; books have authors; products have suppliers. Using OData, clients can navigate over entity relations. Given a product, you can find the supplier. You can also create or remove relationships.

Why are property setters not public in Entity Framework Core?

A class provides methods to manipulate its data and only allows manipulation that keeps the objects’ state correct. That works fine in theory, but in real life objects need to be loaded/materialized from a database and this usually means that property setters must be public. But not with Entity Framework Core!

What is simple OData client in Visual Studio?

Simple.OData.client is a library that supports all OData protocol versions. This is used to consume the OData feed with C# that supports different .NET versions. Let's create a .NET Core console application named and inside the application install the Simple.OData.Client library using this command in package manager console.


1 Answers

the question is quite old, I stumbled across the same issue now. Scalar properties (i.e. int, string, bool) with private setters are not recognized by the ODataConventionModelBuilder, even though it recognizes collections with private setters.

I could solve the problem using EntityTypeConfiguration<T> obtained via the model builder:

public class Article
{
    public string ArticleNr { get; private set; }
    public string SomeProperty { get; private set; }
}


var builder = new ODataConventionModelBuilder();

var articleBuilder = builder.EntityType<Article>();
articleBuilder.HasKey(a => a.ArticleNr);
articleBuilder.Property(a => a.SomeProperty);

builder.EntitySet<Article>("Articles");

var model = builder.GetEdmModel();

This is giving me a model that can be built, it recognizes the key in spite of its private setter and I can also issue queries against SomeProperty. But this way every property must be registered explicitly using a call to Property which seems very error prone when adding new properties. I think it should be able to write a custom convention for it, but I have not tried this so far.

like image 153
Tobias Avatar answered Oct 16 '22 04:10

Tobias