Search code examples
c#entity-frameworklinqlinq-to-entities

Linq - populate lists with outer joins data


Is is possible to have a linq query that populates a class with List for any outer join subqueries?

I've tried various variations of this, but can't get it to work.

Another option would be to populate the class by having more queries, but that would be bad performance wise.

Here's an example, where I try to populate MyClass, using a single query

var result = from p in PersonTable
join cars in CarTable on p.id equals cars.id_person into carsGroup.DefaultIfEmpty()
select new MyClass
{
    Person = new Person
    {
        Id = p.id,
        Name = p.name
    },
    Cars = new List<Car>()
    {
        Id = carsGroup....??

    }
}

    public class MyClass
    {
        public Person Person { get; set; }
        public List<PersonCar> Cars { get; set; }
    }

    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }

    }   

    public class PersonCar
    {
        public int Id { get; set; }
        pubint int IdPerson {get; set;}
        public string Description { get; set; }
    }

Solution

  • The LINQ query you have provide is incorrect. The following is a Test that will demonstrate functionality that you're probably looking for:

        [TestMethod]
        public void TestMethod1()
        {
            var PersonTable = new List<Person>
            {
                new Person
                {
                    Id = 1,
                    Name = "Test1"
                },
                new Person
                {
                    Id = 2,
                    Name = "Test2"
                },
            };
            var CarTable = new List<PersonCar>
            {
                new PersonCar
                {
                    Id = 1,
                    IdPerson = 2
                },
                new PersonCar
                {
                    Id = 2,
                    IdPerson = 3
                }
            };
    
            var result = (from person in PersonTable
                join cars in CarTable on person.Id equals cars.IdPerson into carsGroup
                         from args in carsGroup.DefaultIfEmpty()
                select new MyClass
                {
                    Person = person,
                    Cars = carsGroup.ToList()
                }).ToList();
    
            Assert.AreEqual(2, result.Count);
            Assert.AreEqual(1, result.Count(res => res.Cars.Count == 0));
            Assert.AreEqual(1, result.Count(res => res.Cars.Count == 1));
        }