5

I'm using EF core in a .net core project. After fetching data from ef context, the object's entity's (one-to-many etc...) are automatically loaded.

Here's my code:

 public TimeSheetActivity Get(int id)
 {
     DataSets.TimeSheetActivity dbActivity = db.TimeSheetActivities
                                               .Include(k => k.ProjectFile)
                                               .Include(k => k.MeasurementUnit)
                                               .Include(k => k.TypeOfWork)
                                               .Include(k => k.TimeSheetProject)
                                               .FirstOrDefault(k => k.ID == id);

     return dbActivity == null ? null : _mapper.Map<TimeSheetActivity>(dbActivity);
 }


public Project GetActivityProject(int id)
{
    //db.SaveChanges();

    TimeSheetActivity activity = Get(id);

    if (activity == null)
    {
        return null;
    }

    var dbTimeSheetProject = db.TimeSheetProjects.First(k => k.ID == activity.TimeSheetProjectId);

    var dbProject = db.Projects.First(k => k.ID == dbTimeSheetProject.ProjectId);
    // PROBLEM HERE >> dbProject is loading all entities related
    return _mapper.Map<Project>(dbProject);
}

The problem is marked above and commented in Projects context, here's the project class:

public class Project
    {
        public int ID { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public DateTime DateAdded { get; set; }

        public int? ParentId { get; set; }
        public int? DepartmentId { get; set; }
        public int? CompanyId { get; set; }


        public virtual Department Department { get; set; }
        public virtual Company Company { get; set; }

        public virtual Project Parent { get; set; }

        public virtual List<Project> Activities { get; set; }
        public virtual List<TimeSheetProject> TimeSheetProjects { get; set; }
        public virtual List<ProjectFile> ProjectFiles { get; set; }

    }

Debugging capture:

Debug

11
  • 1
    You cannot rely on the Watch window in this case. Things are loaded on demand, and watching it, is a demand. So it is impossible to see if something is loaded or not. If you want to be sure, better check the query, sent to the SQL-Server, to see what is included. Commented Oct 21, 2019 at 6:59
  • 1
    When you use virtual keyword that means EF load company LazyLoad Commented Oct 21, 2019 at 7:00
  • @Holger i'm loading watch after compiling the line-of-code, so it will result with the actual db object result. plus, automapper threw an exception because it was unable to cast all populated entities.. Commented Oct 21, 2019 at 7:08
  • @AmirNorouzpour i removed the virtual keyword, nothing changed Commented Oct 21, 2019 at 7:08
  • No, it's impossible to watch any "actual db result", the watch window itself is sending further queries to your database, and reloads everything you want to see. Even then you "break all threads" the debugging windows can run your code. If the objects are loaded in one query (with the include) or in many queries(with lazy loading) you can only see in the SQL commands. Do you want to enforce or avoid loading of all objects ? Looks like you enforce with include, everything is loaded, and than you complain everything is loaded. Commented Oct 21, 2019 at 7:15

2 Answers 2

8

I think the problem is this (excerpt from documentation):

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.

https://learn.microsoft.com/en-us/ef/core/querying/related-data#eager-loading

Sign up to request clarification or add additional context in comments.

2 Comments

Interesting this could be a case
Thank you for pointing out the issue, i fixed it by adding an additional linq expression asNoTracking()
6

Regarding @cristi71000 answer, that was the case. my solution was adding AsNoTracking() as the following:

var dbProject = db.Projects.AsNoTracking()...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.