Search code examples
c#linq-to-entitiesrdlclinq

EF1 SelectMany() left join


Is it possible to use SelectMany() and have it behave like a left join?

I am trying to flatten an Entity Object into a tabular format so I can use it as a data source for an .rdlc report. The SelectMany() works like a charm so long as there is a child object, but I want to see all of the parent objects regardless of whether it has children or not.

public class Owner
{
    public int ownerID { get; set; }
    public string ownerName { get; set; }
    public List<Pet> pets { get; set; }
}

public class Pet
{
    public int petID { get; set; }
    public string petName { get; set; }
    public string petType { get; set; }
}

    public void GetOwners()
    {
        List<Owner> owners = new List<Owner>();
        owners.Add(new Owner{ownerID=1, ownerName="Bobby", pets = null});
        owners.Add(new Owner
        {
            ownerID = 2,
            ownerName = "Ricky",
            pets = new List<Pet>(){
                new Pet{petID=1, petName="Smudge", petType="Cat"},
                new Pet{petID=2, petName="Spot", petType="Dog"}}
        });

        var ownersAndPets = owners.SelectMany(o => o.pets
            .Select(p => new { o.ownerName, p.petName }));
    }

This will make ownersAndPets look like:
ownerName = "Ricky", petName = "Smudge"
ownerName = "Ricky", petName = "Spot"

What I need is:
ownerName = "Bobby", petName = null
ownerName = "Ricky", petName = "Smudge"
ownerName = "Ricky", petName = "Spot"


Solution

  • Make sure the dataset is enumerable and then use "DefaultIfEmpty".

            var ownersAndPets = owners
            .SelectMany(o => o.pets
                .DefaultIfEmpty()
                .Select(p => new 
                { 
                    o.ownerName, 
                    p.petName 
                }));
    

    NOTE: I didn't test this particular piece of code, but I have used this before so I know the it can be done.