Search code examples
c#restentity-framework-coreef-code-first

How to Save/Update navigation property in Entity Framework?


I am working on Restful API's using .Net core. Here using Entity Framework Core (code-first migration) for data related operation with SQL Server.

Here I have my main entity which is:

public class Employee
{
    public string Name { get; set; }
    //...other properties.
    public IList<Address> Addresses { get; set; }
}

Where public IList<Address> Addresses { get; set; } is reference navigation.

And Address is a dependent entity which looks like:

public class Address
{
    public string Address1 { get; set; }
    //...other properties.
    public Employee Employee { get; set; }
}

The DbContext is

public class OneToManyDbContext : DbContext
{
    public DbSet<Employee> Employees { get; set; }
    public DbSet<Address> Addresses { get; set; }
    
    //..other config related connection string
}

The API controller for Employee is

[Route("api/[controller]")]
[ApiController]
public class EmployeeController : ControllerBase
{
    protected OneToManyDbContext _dbContext { get; set; }

    public EmployeeController()
    {
        _dbContext = new OneToManyDbContext();
    }

    [HttpPost]
    public void Add(Employee employee)
    {
        _dbContext.Employees.Add(employee);
        _dbContext.SaveChanges();
    }
}

Everything works fine for CRUD related to just Employee entity without Address property. The issue is if I send the nested payload for POST method like

{ 
    "name":"Dennis",
    //..other properties,
    "addresses": {
                     "address1":"Place name",
                     //..other properties
                 } 
}

where addresses is nested key since address is belongs to Employee. Now the Add method fails due to it just expects Employee object without Address.

The Error message is {"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"|8f31a2b1-4bcda017ebe85390.","errors":{"$.Addresses":["The JSON value could not be converted to System.Collections.Generic.IList'1[OneToManyRelationships.Models.Address]. Path: $.Addresses | LineNumber: 4 | BytePositionInLine: 15."]}}

How do I fix this. Is there anything I can do like serialization/deserialization process. I am following Repository Pattern and Unit of work, just to simplify this issue I didn't put it here.

Same question is applicable to Update/Delete methods as well.


Solution

  • There shouldn't be a problem if you POST the employees with a list of addresses. The problem is the way you sent your model. IList<Addreess> is an array of objects in JSON. I.E : [{},{}] you are sending an object inside and object instead. I.E: {{},{}} Following the modeling provided in the question, the JSON object sent should this:

    {
        name: "string",
        //other values
        addresses: 
        [
            {
               "address1":"string",
               //other properties
            },
            {
               "address1":"another string"
               //some other properties
            }
        ]
    }