DavidB
DavidB

Reputation: 2596

List<T> RemoveAll() isn't removing items

I have an object that looks like this:

{
  "Text" : "Another lovely alert",
  "Category" : 2,
  "UserAlerts" : [{ "UserId" : 2 }]
}

This is passed to web API and bound correctly to:

[Key, Column(Order = 0)]
public long UserId { get; set; }

[Key, Column(Order = 1)]
public Guid AlertId { get; set; }

public virtual User User { get; set; }

public virtual Alert Alert { get; set; }

I then run the following, expecting the UserAlert with an ID of two to be removed, but the object is unchanged.

alert.UserAlerts.ToList().RemoveAll(x => userIds.Contains(x.UserId));

alert.UserAlerts.ToList().RemoveAll(x => x.UserId == 2);

The second query is simpler but this doesn't do anything either. I can't figure out where I'm going wrong.

Upvotes: 4

Views: 8647

Answers (3)

Domysee
Domysee

Reputation: 12846

You have to call RemoveAll on alert.UserAlerts, because ToList creates a new collection.
If you remove all items of that collection, it does not change UserAlerts.

alert.UserAlerts.RemoveAll(x => userIds.Contains(x.UserId));

Update:
If UserAlerts is not a List, use the Where extension method (as wudzik said in his answer):

alert.UserAlerts = alert.UserAlerts.Where(x => !userIds.Contains(x.UserId));

Upvotes: 2

Kamil Budziewski
Kamil Budziewski

Reputation: 23087

It's because by using ToList you are creating new List object and then remove items form it, not from original IEnumerable.

Try using this:

alert.UserAlerts = alert.UserAlerts.Where(x => x.UserId != 2);

You can't run RemoveAll on IEnumerable, so I think using Linq here is a good idea. You will have collection of items which do not have UserId=2, which is equivalent to removing all items with UserId=2. You need to reverse your query from RemoveAll and it will work in any case.

Upvotes: 19

Jon Hanna
Jon Hanna

Reputation: 113242

That should certainly remove the elements, but I don't see how you would even notice whether it had or not?

First you create the list with ToList() and then you call RemoveAll() to remove some elements from that list, but since you haven't stored that list anywhere, you're just going to get the number of items removed back.

Upvotes: 4

Related Questions