Simon
Simon

Reputation: 8357

Use LINQ to get a items in a list

I am using C# VS2013 Express and would like some help to code a LINQ statement.

Each MapCompany has a list of MapLocations, and both the MapCompany and MapLocation have a userName field.

Here is my code:

IEnumerable<CanFindLocation.Models.MapCompany> mapCompanies = await db.mapCompanies.Where(mc => mc.userName.Equals(userName)).ToListAsync();
List<MapLocation> mapLocations = new List<MapLocation>();
foreach (var mapCompany in mapCompanies)
{
    foreach (var mapLocation in mapCompany.mapLocations)
    {
        if (mapLocation.userName.Equals(userName))
        {
            mapLocations.Add(mapLocation);
        }
    }
}

I am new to LINQ and would like to write a LINQ statement that will get all MapLocations that have a specific userName.

My above code works, but I would like some help to please code this as a LINQ statement.

Upvotes: 1

Views: 108

Answers (1)

Matthew Haugen
Matthew Haugen

Reputation: 13286

If I'm not mistaken,

IEnumerable<CanFindLocation.Models.MapCompany> mapCompanies = await db.mapCompanies.Where(mc => mc.userName.Equals(userName)).ToListAsync();

var mapLocations = mapCompanies.SelectMany(mapCompany => mapCompany.mapLocations)
                               .Where(mapLocation => mapLocation.userName.Equals(username));

or as suggested by Marcel B in a comment, query syntax:

var mapLocations = from mapCompany in mapCompanies
                   from mapLocation in mapCompany.mapCompanies
                   where mapLocation.userName.Equals(username)
                   select mapLocation;

And, of course, I'd do that for this case and any other I could, but if you typically have trouble with writing LINQ expressions like this, you could also use the yield return pattern. Again, I wouldn't here, but I'll include that as well.

public IEnumerable<MapLocation> GetLocations(IEnumerable<CanFindLocation.Models.MapCompany> mapCompanies)
{
    foreach (var mapCompany in mapCompanies)
    {
        foreach (var mapLocation in mapCompany.mapLocations)
        {
            if (mapLocation.userName.Equals(userName))
            {
                yield return mapLocation;
            }
        }
    }
}

Obviously this doesn't answer your question, my first code block does that, but this would still be a cleaner and generally better way of doing it out the way you had, since it would allow you to benefit from the deferred nature of IEnumerable<T>.

Upvotes: 5

Related Questions