Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework is eager loading a single entity

The abridged version of my WebApi controller is like so:

[HttpGet, Route("")]
public async Task<IHttpActionResult> Search(bool includeEntities)
{
    IQueryable<VersionTopic> results = DbContext.VersionTopics;
    if (includeEntities)
    {
        results = results.Include(o => o.CreatedBy);
        results = results.Include(o => o.LastSavedBy);
        results = results.Include(o => o.Topic.LastSavedBy);
        results = results.Include(o => o.Topic.CreatedBy);
        results = results.Include(o => o.Topic.PACKType.LastSavedBy);
        // etc...
    }

    results = results.OrderBy(o => o.SortOrder);

    return Ok(result.ToList());
}

For some reason, the LastSavedBy entity is ALWAYS populated, even when the includeEntities parameter is false.

Why would it be eager loading just this one entity but none of the others (as is required)?

Here's a screenshot:

enter image description here

My model is defined as so:

public class VersionTopic
{
    [Key]
    [Required]
    public Guid VersionTopicId { get; set; }

    [Required]
    [Index("IX_VersionTopic_VersionId_TopicId", IsUnique = true, Order = 0)]
    public Guid VersionId { get; set; }

    [Required]
    [Index("IX_VersionTopic_VersionId_TopicId", IsUnique = true, Order = 1)]
    public Guid TopicId { get; set; }

    [Required(AllowEmptyStrings = true)]
    [MaxLength(250)]
    public string Name { get; set; }

    public string KeyMessage { get; set; }

    [Required]
    public int SortOrder { get; set; }

    [Required]
    public Guid CreatedById { get; set; }

    [Required]
    public DateTime CreatedDate { get; set; }

    [Required]
    public Guid LastSavedById { get; set; }

    [Required]
    public DateTime LastSavedDate { get; set; }

    public virtual ICollection<VersionRecommendation> VersionRecommendations { get; set; } = new List<VersionRecommendation>();

    [ForeignKey("CreatedById")]
    public virtual ApplicationUser CreatedBy { get; set; }

    [ForeignKey("LastSavedById")]
    public virtual ApplicationUser LastSavedBy { get; set; }

    [ForeignKey("TopicId")]
    public virtual Topic Topic { get; set; }

    [ForeignKey("VersionId")]
    public virtual Version Version { get; set; }

    public VersionTopic()
    {
        VersionTopicId = Guid.NewGuid();
    }
}
like image 707
Sean Avatar asked May 03 '26 17:05

Sean


1 Answers

It's basically explained in the following Tip from Loading Related Data - Eager Loading section of the EF Core documentation, but the same applies to EF6 and below:

Entity Framework Core will automatically fix-up navigation properties to any other entities that were previously loaded into the context instance. So even if you don't explicitly include the data for a navigation property, the property may still be populated if some or all of the related entities were previously loaded.

Unfortunately this behavior is not controllable, so the only options to avoid it is to use fresh new DbContext (or manually cleaning up the navigation properties which are not needed, but that's annoying and easy to forget).

like image 77
Ivan Stoev Avatar answered May 05 '26 08:05

Ivan Stoev