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.

4
  • @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 (stackoverflow.com/questions/853526/…), but doesnt work in my case (because I did search) Commented Feb 1, 2022 at 1:16
  • Please create a Minimum 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 Commented Feb 1, 2022 at 1: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. Commented Feb 1, 2022 at 2: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. Commented Feb 1, 2022 at 3:15

1 Answer 1

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));
Sign up to request clarification or add additional context in comments.

8 Comments

This is close, but I need to update the object first into the DB, then remove the object once it has been updated (0 to 1). Afterwards loop into the next object and add the next object into the DB.
Where does your current code do this?
Please make sure your code is complete.
I have added the relevant code as suggested, let me know if this helps please
@AnalyzingTasks - Updated.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.