TonyP
TonyP

Reputation: 5873

Remove entry of a Bindinglist from a Linq results. - 2 birds in one shot?

This Query returns left outer join from two tables.

  var q = from adu in dtAdsUsers.AsEnumerable()
                        join elu in dtElUsers.AsEnumerable() on adu.Field<string>("samAccountName") equals elu.Field<string>("UserLogin") into gj
                        from au in gj.DefaultIfEmpty() //where au.Field<string>("UserLogin")==string.Empty
                        select
                        new
                        {
                            samAccount = adu.Field<string>("samAccountName"),
                            samb = (au == null ? string.Empty : au.Field<string>("UserLogin"))

                        };

Now remove entries from the dtAdusers which is bound to bindinglist bUserList, using code like this

    foreach (var o in q)
                {

                if (o.samb != "")
                    {
                    Debug.WriteLine(o.samAccount);
                    IEnumerable<ADSUtilities.User> ud = from u in bUserList.AsEnumerable()
                                                        where u.sAMAccountName == o.samAccount
                                                        select u;

                    bUserList.RemoveAt(bUserList.IndexOf(ud));


                    }

                }

bUserList.RemoveAt(bUserList.IndexOf(ud)) gives invalid cast exception 1). How to resolve this ? 2). is there a Linq way of removing entries without iterating ?

Upvotes: 0

Views: 964

Answers (1)

ChrisWue
ChrisWue

Reputation: 19020

ud is an IEnumerable while the elements in bUserList are presumably not of IEnumerable this is why bUserList.IndexOf(ud) will fail.

If the query for ud can indeed result in multiple objects then you need to remove them 1 by 1 like this

foreach(var doomed in ud)
    bUserList.Remove(doomed);

If the query for ud is supposed to return only one element then you should change it to:

 ADSUtilities.User ud = bUserList.AsEnumerable().First(u => u.sAMAccountName == o.samAccount);

Then you can do: bUserList.Remove(ud);

Use FirstOrDefault if the query can result in no objects. This will return default(T) (which is null for reference types) instead of throwing an exception.

There is no real "Linq way" of removing elements from a list because you can't enumerate a list and remove items from it at the same time. This would result in an exception. So you always need to identify the items you want to delete first, store them in a separate list and then remove them. You could make an extension method for if you require it more often. Something like this:

 public static RemoveIf<T>(this IList<T> list, Predicate<T> cond)
 {
     var doomed = list.Where(cond).ToList();
     doomed.ForEach(x => list.Remove(x));
 }

Upvotes: 1

Related Questions