简体   繁体   中英

Convert simple ForEach into a Linq statement

I'm a SQL developer by trade so Linq (and C# in general) is a bit foreign to me, nonetheless I have a simple foreach loop that I am thinking might be better served by a Linq query. if nothing else this will be a useful thing to learn even if the problem at hand is not particularly difficult. Here's my code:

bool fireAgain = true;
foreach (var connMan in Dts.Connections)
{
    Dts.Events.FireInformation
        ( 0
          , ""
          , String.Format("Connection Manager {0} has connection string {1}"
          , connMan.Name
          , connMan.ConnectionString)
          , ""
          , 0
          , ref fireAgain
        );
}

I can figure out:

from connMan in Dts.Connections select connMan

easily enough but how do i then pass my connMan into my call to the FireInformation method?

I would not suggest trying to convert this to Linq, because Linq is meant to be used for functional programming, not imperative. If you wanted to compare it to SQL, then it would be without DML.

Dts.Events.FireInformation doesn't seem to return a value that you could select. It probably fires an event or something, and it also uses a ref parameter. That piece of code doesn't look like a query at all, and i think it shouldn't be forced into one. A foreach loop is perfectly fine in this case, as you're actually doing work inside it and not querying data (which is what linq would be for).

If you needed to filter a collection based on some condition, if you need to join separate collections or something like that, then Linq might be a better tool for the job.

In general LINQ would be used to query information. In this case you're also querying the info.

What you could do however is the following:

Dts.Connections.ForEach((conMan) =>
{
    Dts.Events.FireInformation(0, "", String.Format("Connection Manager {0} has connection string {1}", connMan.Name, connMan.ConnectionString), "", 0, ref fireAgain);
}

That is, if Dts.Connections is a List, otherwise you can't do this. (can't tell from your question if it's an IEnumerable or a List)

A workaround would be to create an extension method and the use it anyway. Like this:

public void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach(T item in source)
    {
        action(item);
    }
}

After that, you can use the ForEach method on your source as shown in the example.

Dts.Connections
   .ForEach(connMan => Dts.Events.FireInformation(0, "", String.Format("Connection Manager {0} has connection string {1}", connMan.Name, connMan.ConnectionString), "", 0, ref fireAgain));

If Connections is not a IEnumerable, change first line with ;

Dts.Connections.ToList()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM