ThisGuyKnowsCode
ThisGuyKnowsCode

Reputation: 521

EF code first child collection not populating

I've been banging my head against this for a long time and all of the Googling in the world isn't helping. I know it's got to be something simple.

Models:

public class List {

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }

    public virtual IList<ListItem> ListItems { get; set; }

}

public class ListItem {

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }

    public bool IsComplete { get; set; }

}

When I set:

Configuration.ProxyCreationEnabled = false;

Then the following is null:

context.Lists.First().ListItems.ToList();

When I set:

Configuration.ProxyCreationEnabled = true;

I get the following exception:

Error getting value from 'ListItems' on 'System.Data.Entity.DynamicProxies.List_5C17C9086854159E373744C770F3DDB07BBE4E3E23C2BD0E6B0C5DE3E13E63AD'

I'm not sure how to proceed. How can I access the ListItems through the List?

Upvotes: 0

Views: 819

Answers (2)

DevilSuichiro
DevilSuichiro

Reputation: 1059

context.Lists.First().ListItems.ToList();

let us analyze this for a bit: you want to get the first List in the database, which returns a List object. For the object to be referencable, EF has to materialize the value, so it executes the query for context.Lists.First(); You may see the problem right here: because the property ListItems is a navigation property, it doesn't get fetched from the database, therefore it is null (if it doesnt get loaded due to eager loading, explicit loading).

You have to tell EF you also want the navigation property to be populated, using the Include() function, like:

context.Lists.Include(x=>x.ListItems).First().ListItems.ToList();

Note that the first() call will fail if there is no entry in the Lists database table, so consider the following approach:

var List=context.Lists.Include(x=>x.ListItems).FirstOrDefault();
var ListItems=List==null?null:List.ListItems.ToList();

Upvotes: 1

ThisGuyKnowsCode
ThisGuyKnowsCode

Reputation: 521

I added the following attribute to the model that was being a pain:

[DataContract(IsReference = true)]

That, along with using context.List.Include(x => x.ListItems), and I'm all set. Thank you!

Upvotes: 0

Related Questions