views:

222

answers:

3

I could have sworn that there was an extension method already built for the Queryable class that I just can't find, but maybe I'm thinking of something different.

I'm looking for something along the lines of:

IQueryable<Entity> en = from e in IDB.Entities select e;
en.ForEach(foo => foo.Status = "Complete");

en.Foreach() would essential perform:

foreach(Entity foo in en){
   foo.Status = "Complete";
}

Is this already written? If not, is it possible to write said Extension Method, preferably allowing for any LINQ Table and any Field on that table. Where is a good place to start?

+1  A: 

There is a foreach on a List<>. Roughly something along these lines:

IQueryable<Entity> en = from e in IDB.Entities select e;
en.ToList().ForEach(foo => foo.status = "Complete");
Andrew Robinson
There it is! I had a suspicion that this functionality what already here, I just wasn't looking in the right place. Casting it to a List<> is perfectly acceptable, and this is what I needed.Thanks.
drovani
+2  A: 
public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)
{
    foreach (var item in sequence)
    {
        action(item);
    }
}
jachymko
I would suggest a different name to avoid a conflict on Lists. Perhaps OnEach<T>(..)?
Samuel
@Samuel, I wouldn't. Both functions do the same thing, so you really don't mind being unable to easily call this version on a List. This way, you can simply use ForEach on any IEnumerable`1 - a List or not.
jachymko
This answer was really helpful. The other part of my problem was knowing the keyword to build my own Extension method to perform an action of every item in a sequence. The "Action" delegate got me pointed on the right road to simplifying the fix for all kinds of problems. Thanks.
drovani
+5  A: 

There's nothing in the base class library. Many, many developers have this in their own common library, however, and we have it in MoreLINQ too.

It sort of goes against the spirit of LINQ, in that it's all about side-effects - but it's really useful, so I think pragmatism trumps dogma here.

One thing to note - there's really no point in using a query expression in your example. (It's not entirely redundant, but if you're not exposing the value it doesn't matter.) The select isn't doing anything useful here. You can just do:

IDB.Entities.ForEach(foo => foo.status = "Complete");

Even if you want to do a single "where" or "select" I'd normally use dot notation:

IDB.Entities.Where(foo => foo.Name == "fred")
            .ForEach(foo => foo.status = "Complete");

Only use query expressions where they actually make the code simpler :)

Jon Skeet
Very articulate answer, and I appreciate the response. The actual query expression is much more complicate; I just reduced it for simplicity of the question. Also, thank you for the link to MORELinq. There are a lot of helpful things I've found over there.
drovani