0

I would like to replace the foreach loop in the following code with LINQ ForEach() Expression:

    List<int> idList = new List<int>() { 1, 2, 3 };

    IEnumerable<string> nameList = new List<string>();

    foreach (int id in idList)
    {
       var Name = db.Books.Where(x => x.BookId == id).Select(x => x.BookName);
        nameList.Add(Name);
    }

Any Help Please!!

3
  • 2
    there's a similar question Commented Nov 23, 2016 at 4:49
  • looks like you need to add a type declaration to Name, something like "var Name = db..." Commented Nov 23, 2016 at 4:50
  • @lloyd - That question isn't a duplicate. There's a difference between the C# keyword foreach and the .ForEach extension method. Commented Nov 23, 2016 at 5:00

4 Answers 4

5

Your code doesn't quite work (you're adding an IEnumerable<string> to a List<string>). You also won't need ForEach, since you're constructing the list:

You can do this:

var nameList = idList.SelectMany(id => db.Books.Where(x => x.BookId == id)
                     .Select(x => x.BookName)).ToList();

But then you're hitting the database for each ID. You can grab all the books at once with :

var nameList = db.Books.Where(b => idList.Contains(b.BookId))
                       .Select(b => b.BookName).ToList();

Which will only hit the database once.

Sign up to request clarification or add additional context in comments.

Comments

1

Why not a select?

List<int> idList = new List<int>() { 1, 2, 3 };

List<string> nameList = idList
    .Select(id => db.Books.Where(x => x.BookId == id).Select(x => x.BookName))
    .ToList();

Or better yet: refactorise and select...

int[] idList = new int[] { 1, 2, 3 };

List<string> nameList = db.Books
    .Where(x => idList.Contains(x.BookId))
    .Select(x => x.BookName))
    .ToList();

Comments

0
    nameList.AddRange(
             db.Books.Where(x => idList.Contains(x.BookId))
                     .Select(x => x.BookName)
                     .ToList());

This will generate an IN statement in the SQL, thereby only doing a single select.

One thing to be aware of is the performance of IN degrades as the set (idList in this case) gets bigger. In the case of a large set, you can batch the set and do multiple queries:

int start = 0;
int batch = 1000;
while (start < idList.Count())
{
  var batchSet = idList.Skip(start).Take(batch);
  nameList.AddRange(
             db.Books.Where(x => batchSet.Contains(x.BookId))
                     .Select(x => x.BookName)
                     .ToList());
  start += batch;
}

1 Comment

could you please add an explanation to your answer, so future readers can also learn how it works?
-1

To answer your specific question, you can do this:

List<int> idList = new List<int>() { 1, 2, 3 };

List<string> nameList = new List<string>();

idList.ForEach(id => {
    var Name = db.Books.Where(x => x.BookId == id).Select(x => x.BookName);
    nameList.Add(Name);
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.