ASP.NET 5 and EF – Replace child list with LINQ

I am working on an API controller for an ASP.NET project, and I have ran into an issue. I have a Computer object with a one-to-many relationship with a Services object. When a Computer is added that has an IP identical to an existing Computer in the database, I want to replace the old Computer’s attributes, as well as replace the associated Services collection. However, when I try to replace the Services collection, it adds onto the existing Services instead of replacing it.

Computer Model

public class Computer
{
    public int ComputerId { get; set; }
    public string Ip { get; set; }
    public string Os { get; set; }
    public IList<Service> Services { get; set; }
        
}

Services Model

public class Service
{
    public int ServiceId { get; set; }
    public int ComputerId { get; set; }
    public int Port {get; set;}
    public int Version {get; set;}
}

Computer Controller

[HttpPost]
...
Computer oldComputer = _context.Computers.FirstOrDefault(y => y.Ip == newComputer.Ip);
if(oldComputer != null) {
   oldComputer.Hostname = newComputer.Hostname;
   oldComputer.Os = newComputer.Os;
   oldComputer.Services = newComputer.Services?.ToList(); //this adds new services to old services collection instead of replacing it
}

What changes should I make in order to replace the Services collection instead of adding onto it?

>Solution :

You need to load existing entities and then clear the collection and replace with the new ones.

Computer oldComputer = _context.Computers.Include(c => c.Service).FirstOrDefault(y => y.Ip == newComputer.Ip);
if(oldComputer != null) {
   oldComputer.Hostname = newComputer.Hostname;
   oldComputer.Os = newComputer.Os;
   oldComputer.Services.Clear();
   oldComputer.Services = newComputer.Services?.ToList(); //this adds new services to old services collection instead of replacing it
}

If you can actually do an upsert and delete removed services, it might be more efficient in your case but that bit of model is not apparent to me.

Leave a Reply