How to load all levels of object nested within a class, using Entity Framework 7 linq queries?

I am using Entity Framework 7 to map my application's data access.

Here's an example of the classes I'm using:

[Table("class1")]
public class Class1
{
    public int id { get; set; }
    public int randomProp1 { get; set; }
    public int randomProp2 { get; set; }

    public ICollection<Class2> collectionClass2 { get; set; }
    public ICollection<Class3> collectionClass3 { get; set; }
}

[Table("class2")]
public class Class2
{
    public int id { get; set; }
    public int idClass1 { get; set; }
    public int randomProp { get; set; }

    [ForeignKey("idClass1")]
    public Class1 class1 { get; set; }
}

[Table("class3")]
public class Class3
{
    public int id { get; set; }
    public int randomProp { get; set; }
    public int randomProp2 { get; set; }
    public int idClass2 { get; set; }

    [ForeignKey("idClass1")]
    public Class1 class1 { get; set; }

    public ICollection<Class4> collectionClass4 { get; set; }
}

[Table("class4")]
public class Class4
{
    public int id { get; set; }
    public int idClass3 { get; set; }
    public int randomProp4 { get; set; }

    [ForeignKey("idClass3")]
    public Class3 class3 { get; set; }
}

I am trying to get all this structure. To do so, I have the following method:

public List<Class1> GetAll()
{
    return _ctx.Class1
                .Include(x => x.collectionClass2)
                .Include(x => x.collectionClass3)
                .Include(x => x.collectionClass3.Select(c => c.collectionClass4))
                .ToList();
}

However, when I try to execute this method, I get the following exception:

An exception of type 'System.InvalidCastException' occurred in EntityFramework.Core.dll but was not handled in user code Additional information: Cannot convert an object of type 'Remotion.Linq.Clauses.Expressions.SubQueryExpression' to type 'System.Linq.Expressions.MemberExpression'.

If I remove .Include(x => x.collectionClass3.Select(c => c.collectionClass4)) from the query, it retrieves the data, but the class4 collection nested within class3 comes as a null property.

I also tried to put .ThenInclude(x => x.Select(c => c.collectionClass4)) instead as I saw it in some examples in the internet, but it gets the following exception:

An exception of type 'System.ArgumentException' occurred in EntityFramework.Core.dll but was not handled in user code Additional information: The properties expression 'x => {from Class3 c in x select [c].collectionClass4}' is not valid. The expression should represent a property access: 't => t.MyProperty'. When specifying multiple properties use an anonymous type: 't => new { t.MyProperty1, t.MyProperty2 }'.

Upvotes: 2

Views: 1080

Answers (1)

Gert Arnold
Gert Arnold

Reputation: 109251

ThenInclude comes after an Include to indicate that nested objects must be included as well:

.Include(x => x.collectionClass3)
    .ThenInclude(x => x.collectionClass4)

Upvotes: 2

Related Questions