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?
CodePudding user response:
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.
CodePudding user response:
Maybe you could try to do a Clear() on the Services on the line prior to the one where you set the new one.
oldComputer.Services.Clear();