Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get ODATA to serialize NotMapped property

I have a WebAPI backend that provides inventory information, etc. to various clients, using ODATA v3 (I cannot use v4 due to a restriction in a component that we use). The inventory database is quite large (100K+ records) and ODATA is great for server-side filtering, pagination, etc. and keeping the data transfers lean.

The inventory records have some properties that are not mapped, but rather calculated and populated on the fly as the queries are made. For example:

[NotMapped]
public decimal RebateAmount { get; set; }

The problem is that ODATA ignores any NotMapped properties, so they never get sent back to the clients.

I know this has been asked before, but that was a while ago now so I was hoping that support for this has been added by now or that somebody has a simple workaround (short of letting EF create these fields in the DB).

I have tried this ugly workaround, but it did not work (RebateAmount still does not get included by ODATA):

private decimal _rebateAmount;
public decimal RebateAmount { get {return _rebateAmount; } }

public void SetRebateAmount(decimal amount)
{
   _rebateAmount = amount;
}

Is there a (preferably simple) way to include non-DB properties in ODATA result sets?

Edit 1/7/2017 For this to be useful in my scenario, ODATA needs to also include the calculated fields in its metadata, otherwise the auto-generated (client-side) proxy classes will not include them.

like image 606
Lars335 Avatar asked Jan 05 '17 18:01

Lars335


3 Answers

The easiest way (at least for EF Core): Use fluent-api!

Instead of NotMapped-Attribute you can define it like this:

modelBuilder.Entity<Product>().Ignore(p => p.RebateAmount);

For EF6 you should also look at this question: EF Code First prevent property mapping with Fluent API

like image 81
Joshit Avatar answered Nov 09 '22 09:11

Joshit


I know this is an old post but in the WebApiConfig file just add the following and it will expose the "NotMapped" property.

builder.StructuralTypes.First(t => t.ClrType == typeof(YourModel)).AddProperty(typeof(YourModel).GetProperty("RebateAmount"));

Where "builder" is your IEdmModel. Most likely in your "GetEdmModel" method.

like image 43
goroth Avatar answered Nov 09 '22 08:11

goroth


One approach could be by creating OData EDMModel with a DTO object with the additional computed property.

Please check this answer which has the implemetation details to do this: Mapping OData query against a DTO to another entity?

The DTO can be mapped by a View at Database server or can be calculated in controller by using OdataQueryOptions.

like image 2
Ankit Avatar answered Nov 09 '22 09:11

Ankit