question

IgorBaldacci-6930 avatar image
0 Votes"
IgorBaldacci-6930 asked IgorBaldacci-6930 commented

How to define Web Api for many-to-many insert using DTO

Hi all,
I'm trying to define a Web API to insert data in a many-to-many tables structure. I'm using EF Core code first approch.

This is my model data:

 public class Giocata
 {
     public int GiocataId { get; set; }
     public string NomeGiocata { get; set; }
    
     // FK GiocateRuote
     public ICollection<GiocataRuota> GiocateRuote { get; set; }
 }    
    
 public class Ruota
 {
     public int RuotaId { get; set; }
     public string NomeRuota { get; set; }
    
     // FK GiocateRuote
     public ICollection<GiocataRuota> GiocateRuote { get; set; }
 }    
    
 public class GiocataRuota
 {
     public int GiocataRuotaId { get; set; }
     // FK RuotaId
     public int RuotaId { get; set; }
     public Ruota Ruota { get; set; }
     // FK GiocataId
     public int GiocataId { get; set; }
     public Giocata Giocata { get; set; }
 }

In order to pass datas to my web api I'm using the dto, so I have also defined:

 public class GiocataDTO
 {
     public Giocata Giocata { get; set; }
     public List<Ruota> lstRuota { get; set; }
     public List<Sortita> lstSortita { get; set; }
     public List<Importo> lstImporto { get; set; }
 }

So, in my controller I have defined the method as follow:

 [HttpPost]
 [Route("[action]")]
 [Route("api/giocate/PostSalvaGiocata")]
 public async Task<ActionResult<GiocataDTO>> PostSalvaGiocata([FromBody] GiocataDTO giocatadto)
 {
     var lstGiocateRuota = new List<GiocataRuota>();
     foreach (var ruota in giocatadto.lstRuota)
     {
         var giocataruotain = new GiocataRuota { Ruota = ruota, Giocata = giocatadto.Giocata };
         lstGiocateRuota.Add(giocataruotain);
     }
    
     await _context.AddRangeAsync(giocatadto.Giocata, giocatadto.lstRuota, lstGiocateRuota);
     await _context.SaveChangesAsync();
    
     return CreatedAtAction("postSalvaGiocata", new { id = giocatadto.Giocata.GiocataId }, giocatadto.Giocata);
 }

Now when I try to consume the Api I receive this error:

System.InvalidOperationException: The entity type 'List<Ruota>' was not found. Ensure that the entity type has been added to the model.

This is my forst time I use a many-to-many procedure so I'm not able to understand where the problem is.
Could someone halp me please to understand what can I check?

Thank you for any kind of help.
Igor

dotnet-entity-framework-core
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

DuaneArnold-0443 avatar image
0 Votes"
DuaneArnold-0443 answered IgorBaldacci-6930 commented

IMHO, you should be using the DAO pattern with the DTO pattern. A DAO is on a table per DAO basis.

The DAO is responsible for doing CRUD for a table. The controller should be calling DAO(s) that would be in a classlib project like a data access layer implementing SoC.

https://en.wikipedia.org/wiki/Separation_of_concerns

https://javarevisited.blogspot.com/2013/01/data-access-object-dao-design-pattern-java-tutorial-example.html

https://docs.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/architectural-principles

As you insert a parent object using the insert method in its DAO, you return the ID of the parent so it can be applied to the foreign-key property of the child that will be inserted into the database with its DAO. You can get the ID of any the inserted EF object right after it is inserted by addressing the EF object's ID property.

Here is a a solution where the WebAPI is using the DTO and DAO in the DAL to do CRUD operations. However, it's not doing any one-2-many.

https://github.com/darnold924/PublishingCompany/tree/master/DAL

You will need to use a System.Transaction scope on a give parent then child inserts.

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi DuaneArnold, thank you for your replay.
I need to study all your links to understand your suggestion.

In my mind, I thought that I was make a mistake in the write of my code, so I was waitnig for a correction in some part of it. But, you are proposing me to make a different approch of the problem, with a tecnology (maybe) that I don't understand.

Thanks for now.
Igor

0 Votes 0 ·