1

Closed

Collection should not be loaded on navigation property

description

I have a pretty simple model consisting of a Post with a User navigation property (public User CreatedByUser { get; set; }). The User object also has a navigation property for the collection of posts created by that user (public ICollection<Post> PostsCreated { get; set; }). If I make a request (db.Posts.Include(x => x.CreatedByUser)), the CreatedByUser contains the appropriate User, but the PostsCreated collection has also been populated even though I haven't explicitly loaded it via Include. Since I have opted to disable lazy loading in my context, I would only expect that the User object be populated, but I would not expect the collection of posts created to be populated. I've included the Post mapping below:

this.HasRequired(t => t.CreatedByUser).WithMany(t => t.PostsCreated).HasForeignKey(d => d.CreatedById);

To further test this, I have a complex type collection (public ICollection<PromoPost> PromoPosts { get; set; }) on the Post object. If I don't include that property explicitly, the collection is empty; however, if I include it the collection is populated as expected. This is the behavior I would expect on the collections associated with included entities.

I'm hoping someone can confirm if this is expected behavior or if this is something that may need to be addressed another way.
Closed Mar 2, 2013 at 9:30 PM by ajcvickers
By design; see comments.

comments

corydeppen wrote Dec 28, 2012 at 6:17 AM

Something else I just noticed is that if I limit the results using FirstOrDefault the nested collections are not loaded, but returning a list will load the nested collections regardless of whether I have disabled lazy loading or not.

kayub wrote Jan 3, 2013 at 5:19 PM

Did you post this on SO? I'd be interested in seeing what people think.

ajcvickers wrote Mar 2, 2013 at 9:29 PM

@corydeppen The behavior you are seeing is as expected. Let me try to explain. When EF executes a LINQ query in the default way it does two things with the results. The first is obvious: the results are returned to the caller. Second, it takes each returned entry and creates an entry for it in its internal cache. This allows changes to the entity to be tracked so that appropriate updates can later be sent to the database.

One of the things that the cache (a.k.a. the state manager) does is to keep relationships between entities in sync. This means that when a Post entity is returned in the query the state manager will check whether or not it is related to a User that is also returned in the query (or is already in the state manager). The same thing happens when a User entity is returned--a check will be made for any related Post entities. If a relationship between two entities exists then EF will make sure that the navigation properties between the two entities are in sync. That is, reference navigation properties (e.g. from Post to User) will be set and collection navigation properties (e.g. the Posts on User) will be populated.

Note that this does not involve bringing back any extra entities in the query. It just means that for any entities that are returned the relationships between those entities will have been set. This behavior is typically referred to a "fixup".

Hope this helps.

Thanks,
Arthur