简体   繁体   中英

I want to convert this foreach loop to a LINQ statement

I am not an great at linq by any means but I usually have no issues with a problem of this sort. I want to convert this foreach statement to a LINQ statement:

var existingKeys = new List<int>();
foreach (var taskKey in request.Keys)
        {
             existingKeys.AddRange(_context.WebTaskGroups
                 .Where(x => x.TaskGroupNameKey == key && x.TaskKey == taskKey)
                 .Select(x => x.TaskGroupNameKey));
        }

I thought this would do it:

var existingKeys = request.Keys.ForEach(taskKey => _context.WebTaskGroups
        .Where(x => x.TaskGroupNameKey == key && x.TaskKey == taskKey)
        .Select(x => x.TaskGroupNameKey));

That apparently returns a void not a list... This:

  var existingKeys = request.Keys.Select(taskKey => 
            _context.WebTaskGroups
            .Where(x => x.TaskGroupNameKey == key && x.TaskKey == taskKey)
            .Select(keys => keys.TaskGroupNameKey));

Gives me an "IEnumerable<IQueryable<int>>. So what is the secret sauce that I am missing here?

You shouldn't be performing N database queries in the first place. Using LINQ to perform those N queries instead of a foreach loop doesn't fix that core problem.

You need to re-conceptualize your query so that you have just one query that gets all of the data that you need. In this case that means getting all of the items that match your collection of keys rather than trying to match a single key and then performing N of those queries.

var requestedKeys = request.Keys;
var existingKeys = _context.WebTaskGroups
                 .Where(x => x.TaskGroupNameKey == key && 
                     requestedKeys.Contains(x.TaskKey))
                 .Select(x => x.TaskGroupNameKey))
                 .ToList();
var existingKeys = request
    .SelectMany(r => r.Keys)
    .SelectMany(tk =>
        _context.WebTaskGroups
            .Where(x.TaskGroupNameKey == key && x.TaskKey == tk)
            .Select(x => x.TaskGroupNameKey))
    .ToList();
var existingKeys = _context.WebTaskGroups
             .Where(x => x.TaskGroupNameKey == key && request.Keys.Contains(x.TaskKey))
             .Select(x => x.TaskGroupNameKey)
             .ToList();

ForEach return a void: http://msdn.microsoft.com/en-us/library/bwabdf9z(v=vs.110).aspx

ForEch: Performs the specified action on each element of the List.

So what to do, is for each item in the list of request.Keys to perform the action to add to the list of existingKeys.

For example:

request.Keys.ForEach(taskKey => 
         existingKeys.AddRange(_context.WebTaskGroups
             .Where(x => x.TaskGroupNameKey == key && x.TaskKey == taskKey)
             .Select(x => x.TaskGroupNameKey));

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