Search code examples
c#entity-framework-coreef-code-firstlazy-loadingglobal-query-filter

EF Core Navigation Property is loaded although Query Filter is configured


I use EF Core 5.0.4 with a MS SQL Server and Lazy Loading. My entities all derive from BaseEntity which contains a Deleted property. For all entities I configured a global query filter which allows to load only entities where Deleted is set to false. Now I've got a Project entity and an Appointment entity and a n:m entity ProjectAppointment.

public class ProjectAppointment : BaseEntity
{
    public ProjectAppointment(Guid? id, Project project, Appointment appointment) : base(id)
    {
        Project = project;
        Appointment = appointment;
    }

    public ProjectAppointment(Guid? id, Guid projectId, Guid appointmentId) : base(id)
    {
        ProjectId = projectId;
        AppointmentId = appointmentId;
    }

    public ProjectAppointment()
    {
    }

    public Guid ProjectId { get; private set; }
    public virtual Project Project { get; private set; }
    public Guid AppointmentId { get; private set; }
    public virtual Appointment Appointment { get; private set; }
}

All three types derive from BaseEntity. If I load an appointment from database which contains a projectAppointment with was recently changed to Deleted = true, this navigation property will still be returned by ef core although the query filter should avoid this:

enter image description here

I created a simplified repository to demonstrate the issue. It also occurs without lazy loading.

How can I configure entity framework to not lazy load navigation properties with Deleted = true?


Solution

  • Well, I have checked your sample.

    You have loaded record, updated and trying to check that this records is not appears in other collection. Problem here that ChangeTracker already knows about this records and knows to which collection it should be applied even it is not returned from database.

    Workarounds:

    • _appContext.Entry(pa).State = EntityState.Detached;
      
    • _appContext.ChangeTracker.Clear();
      
    • Update in one DbContext, load in another.