Entity Framework REST API - How to post process data?

c# entity-framework-core nancy

Question

I'm coding a REST Api in .NET Core with NancyFX right now that retrieves data from a database using Entity Framework. The tables inside the database have various fields that equal the ones inside my model classes. However I don't want to expose all fields via the Api.

e.g:

DB table Persons:

  • ID
  • Name
  • Sex
  • Age

DB table Shoes:

  • ID
  • PersonID
  • Model
  • Colour

My REST endpoint /persons should only send ID, Name, Sex without Age together with a list of Shoes (only Model):

{id: 1, name: "Max", sex: "m", "shoes": [{"id": 1, "model": "AirMax"}]}

At first I thought the best way would be to specify the fields I want to show by specifying them inside Select(). But when I have joined tables, I can't set a Select() on the joined ones. So I'm iterating over the entity lists right now and create a new list that contains the wanted properties:

List<object> newPersonList = new List<object>();
  foreach(Person p in db.Persons) {
    List<object> newShoesList = new List<object>();
      foreach(Shoe s in p.Shoes) {
        newShoeList.Add(new {...});
      }
  }
  newPersonList.Add(new {...});
}

But I'm not sure if this form of post-processing is the right one. This could get difficult if I have multiple sub-related tables. However I don't want to expose all model properties via REST. Is there an alternative?

1
0
8/16/2018 2:38:58 PM

Popular Answer

Couple of things to consider:

1) You only want to select from the database the fields that you need to return. Otherwise, you are putting more strain on your database than you need to.

2) You don't want to return your EF entities directly from your API. This will tightly couple your data access and your client together which is something you want to avoid. You should use projection to only select the field you want and return those via custom DTOs. Both LINQ's select method and a mapping tool like AutoMapper (AM) work for this. Personally, I prefer AM's projection over LINQ's select due to the fact that your mapping is done independently from your query which allows for reuse when possible. It also simplifies your queries in code (although does add complexity to configure AM and it's mappings).

I had a question/answer about a year ago that dealt with grouping so it's not exactly the same as your example, but it shows all the necessary code to handle your scenario using AM. Hope it helps you out. LINQ GroupBy Aggregation with AutoMapper

Also, here is the link to AM's projetion documentation: http://docs.automapper.org/en/stable/Projection.html

1
8/16/2018 3:02:44 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow