I have some complex scenarios, but I will show them here as simple. So, my context class is pretty simple:
public class AppDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("data source=DILSHODKPC;integrated security=True;Database=ODataTEst; MultipleActiveResultSets=true");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var student = modelBuilder.Entity<Student>();
student.HasKey(s => s.Id);
}
public IQueryable<T> GetEntities<T>() where T : class
{
return Set<T>();
}
}
My model is simple too:
public class Student
{
public Guid Id { get; set; }
public string Name { get; set; }
public int Score { get; set; }
}
I have 8 records on the database:
My problem is when I add a query to the existing entity framework is tracking all entities. Look at two scenarios:
Scenario 1:
AppDbContext appDbContext = new AppDbContext();
var query1 = appDbContext.GetEntities<Student>().Where(s => s.Score > 3);
var query2 = query1.Where(s => s.Name == "Messi");
var loadedEntitiesCount = query2.ToList().Count();//Count is 4. It is good
var trackedEntitiesCount = appDbContext.ChangeTracker.Entries<Student>().Select(e => e.Entity).Count();//Count is 4. It is good
In this scenario, everything is expected.
Scenario 2:
static void Main(string[] args)
{
AppDbContext appDbContext = new AppDbContext();
var query1 = GetFirstQuery(appDbContext);
var query2 = query1.Where(s => s.Name == "Messi");
var loadedEntitiesCount = query2.ToList().Count();//Count is 4. It is good
var trackedEntitiesCount = appDbContext.ChangeTracker.Entries<Student>().Select(e => e.Entity).Count();//Count is 8. Confusing
}
static IEnumerable<Student> GetFirstQuery(AppDbContext appDbContext)
{
return appDbContext.GetEntities<Student>().Where(s => s.Score > 3);
}
In this scenario, the count of tracked entities is 8. I was not expecting it
Scenario 3:
AppDbContext appDbContext = new AppDbContext();
var query1 = GetFirstQuery(appDbContext).AsQueryable();
var query2 = query1.Where(s => s.Name == "Messi");
var loadedEntitiesCount = query2.ToList().Count();//Count is 4. It is good
var trackedEntitiesCount = appDbContext.ChangeTracker.Entries<Student>().Select(e => e.Entity).Count();//Count is 4. It is good
The count of tracked entities is 4.
The question is why ef tracking all entities in Scenario 2? Is it something expected? What are best practices to add query on existing query with different kinds of collections? (IEnumerable, IQueryable)