How to query a list inside a list using Linq?

entity-framework lambda linq

Question

I have Store List (storeList) object. (Consists of list of Stores) Each Store has list of Addresses. Each address have AddressType property that can be PHYSICAL, ALTERNATIVE or MAILING.

I am trying to return PHYSICAL Address object so I can modify its properties:

This is my first attempt:

StoreAddressList result = 
    (from str in storeList
     where
     str.AssetAddresses.Any(p => p.AddressType.Name == "PHYSICAL")
     select str.AssetAddresses).FirstOrDefault();

As a result I expect to get list with only one item (where address type is PHYSICAL), but I get list with 3 items (with all three types). What's wrong here?

Thanks

1
3
12/6/2011 4:21:46 PM

Accepted Answer

Flatten the list of list of addresses by projecting each store to its list of addresses, use SelectMany to achieve the flattening, and then take only those where the address type is physical:

var addressesToModify = 
    storeList.SelectMany(store => store.AssetAddresses)
             .Where(address => address.AddressType.Name == "PHYSICAL");

In query syntax:

var addressesToModify =
    from store in storeList
    from address in store.AssetAddresses
    where address.AddressType.Name == "PHYSICAL"
    select address;

Notice how it reads exactly like we described. From each store in the storeList, from each address in store.AssetAddresses where address is a physical address, select address.

Now iterate the results of the query and modify as needed.

Also, I strongly suggest making an enum

public enum AddressType { Physical, Alternative, Mailing }

and changing Address.AddressType to be of this type

public AddressType AddressType { get; }

and then you can write

where address.AddressType == AddressType.Physical

or

.Where(address => address.AddressType == AddressType.Physical);
10
12/6/2011 4:28:29 PM

Popular Answer

You need to use SelectMany to flattern out the list of addresses.

var result =
  storeList
  .SelectMany(store => store.AssetAddress)
  .Where(address => address.AddressType == "PHYSICAL")
  .FirstOrDefault();

I'm guessing there will also be a where on the storeList so that you only get the address of the store you're interested in.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow