grozdeto
grozdeto

Reputation: 1379

How to use linq to iterate over all images but only search a part of the string in those images?

I have a collection of images. All of them are named according to what they used for. for logos they follow the convention business_logo, for logbooks they follow a convention business_logbook.

Now I want to write a LinQ iterating over all images, find the one that contains (_logbook), so I can delete the image in that logbook. If I remove it from the context it will remove it from wwwroot automatically.

Also the query needs to be async.

Upvotes: 0

Views: 35

Answers (1)

Joshua Sprague
Joshua Sprague

Reputation: 360

You select the items where the path contains the string you are searching for:

public class Image
{
    public string Name { get; set; }
}

var _imageRepo = new Collection<Image>()
{
    new Image { Name = "business_logo_123954.png" },
    new Image { Name = "business_logbook_529429.png" },
    new Image { Name = "business_logo_81957.png" },
    new Image { Name = "business_logbook_234820.png" }
};

var logBookImages = await _imageRepo
    .Where(x => x.Name.Contains("_logbook"))
    .ToListAsync();

// Or you can check that the file name starts with business_logbook. 
var logBookImages = await _imageRepo
    .Where(x => x.Name.StartsWith("business_logbook"))
    .ToListAsync();

Linq queries are neither async or sync. A query is not executed until you call one of the various materialization methods on the query. In your case, since you want the data to mbe materialized async, you'll need to call .ToListAsync() instead of .ToList(). Doing so, you'll also need to add the await keyword to the statement.

I would suggest getting your collection of items first and then deleting them, but it's a matter of preference and what database system/pattern you're using.

var logBookImagePathsToDelete = await _imageRepo
    .Where(x => x.Path.StartsWith("business_logbook"))
    .Select(x => x.Path)
    .ToListAsync();

foreach(var path in logBookImagePathsToDelete)
    await DeleteImageAsync(path);

If you wanted to do it all in one action without creating any variables, you could do something similar to the following:

(await _imageRepo   
    .Where(x => x.Path.Contains("_logbook"))
    .Select(x => x.Path)
    .ToListAsync())
    .ForEach(async path => await DeleteImageAsync(path));

Upvotes: 1

Related Questions