Starfish
Starfish

Reputation: 3584

Replacing ElementAt in a LINQ query to cover multiple elements

I want to retrieve a list of Orders based on a multiple Location lists.

For context: a Group can have a multiple Locations (one-to-many) and an Order has one Location (many-to-one). I want to get all the Orders of a Group based on the Locations it has.

The following works for the first element in the list of Groups:

List<Order> orders = _context.Orders
    .Where(o => groups.ElementAt(0).Locations.Contains(o.Location))
    .ToList()

I want to change it such that it will not only check the first Group element, but all of them. Help is appreciated.

Upvotes: 0

Views: 132

Answers (2)

Markus
Markus

Reputation: 22511

As groups is only a variable, you can use SelectMany to flatten the nested hierarchy before running the query:

var locations = groups.SelectMany(x => x.Locations).ToArray();

This basically changes a nested hierarchy

G1
  L11
  L12
G2
  L21
  L22

to a flat list of locations:

L11
L12
L21
L22

After that, you can use the locations in the query:

List<Order> orders = _context.Orders
  .Where(o => locations.Contains(o.Location))
  .ToList()

If the groups can contain duplicate locations, you could also add a Distinct after the SelectMany.

Upvotes: 2

Mernayi
Mernayi

Reputation: 257

Is this what you are looking for?

var result = orders
    .Where(o => groups.All(f => 
        f.Locations.Contains(o.Location))).ToList();

Upvotes: 0

Related Questions