0

I have a DTO:

public class UserDTO 
{
  public int uid {get;set;} 
  public string name {get;set;} 
}
// example of what the udto gets as a request from the front-end
var theList = new List<UserDTO>()
{
  new UserDTO { uid = 1, name = "Bob Smith" },
  new UserDTO { uid = 2, name = "Jane Jones" },
};

In the DB: Bob's exists with a status of 0 and Janes does not exist in the DB. So the loop checks to see if the user exists with a status of 0, if so, then updates the DB status from 0 to 1 with _myCtx.Update(). Then once updated, it removes Bob's object because I dont want to duplicate Bob as he exists already, I need Bobs object removed and then move on to the next loop where it adds Jane into the DB.

public async Task<IActionResult> AddUser([FromBody] List<UserDTO> udto)
{
  var toRemove = new HashSet<UserDTO>();
  foreach(var item in udto)
  {
    var userFalse = await _myCtx.Users.SingleOrDefaultAsync(o => o.uid == item.uid && o.status == 0);
    if(userFalse != null) // if user found, I want to update
    {
      item.Status = 1;
      _myCtx.Users.Update(userFalse); 
      await _myCtx.SaveChanges(); //save into the DB the status to 1
      if(item.uid == userFalse.uid){ toRemove.Add(item); } //need Bob removed here
    } // below I want to add if they don't exist
    udto.RemoveAll(toRemove.Contains);
    item.name = udto.name;
    var myEntity = _mapper.Map(item);
    await _myCtx.Users.AddAsync(myEntity);
    // Jane gets added, but so does Bob as a duplicate
  }
  await _myCtx.SaveChangesAsync();
  return Ok("User Added");
}

The item is removed AFTER the loop is done and the reason its adding it to the DB. Is there a way to remove Bob before it continues after or inside the if clause so it does not get added to the DB? Thank you all.

  • @Selvin well youre not helpful - if its asked many times, you should have provided one link and not just down vote it... I found this one already (https://stackoverflow.com/questions/853526/using-linq-to-remove-elements-from-a-listt), but doesnt work in my case (because I did search) – AnalyzingTasks Feb 01 '22 at 01:16
  • Please create a [Minimum Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example). We don't know what `_myCtx` is. And all the `async` nonsense makes your code hard to follow and is likely causing you problems – Nigel Feb 01 '22 at 01:29
  • 1
    I have dupe hammered your question because I believe it is a duplicate - but if it isn't then please just update your question (to make it quite distinct from the linked question) and it can possibly be reopened. – slugster Feb 01 '22 at 02:33
  • @slugster It's similiar but has an update and insert tasks inside the loop into a DB, which the link you provided as a duplicate, I also added that as a reference above to Selvin, but that did not answer my question completely. – AnalyzingTasks Feb 01 '22 at 03:15

1 Answers1

3

Your code appears to be modifying a collection while you're iterating over it. That can't happen.

You can remove the loop easily though.

It seems to me that you're trying to do this:

var uids = udto.Select(x => x.uid).ToArray();

var users =
    _myCtx
        .Users
        .Where(x => x.status == 0)
        .Where(x => uids.Contains(x.uid))
        .ToArray();
        
foreach (var user in users)
{
    user.status = 1;
}

await _myCtx.SaveChanges();

var uids2 = users.Select(x => x.uid).ToArray();

udto.RemoveAll(x => uids2.Contains(x.uid));
Enigmativity
  • 113,464
  • 11
  • 89
  • 172