Inconsistent behaviors when loading related entities explicitly with Query and Include
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
Explicit loading works fine when I want to load navigation properties of an (detached) entity.
But when my entities get complex and I try to call `Query` and `Include`s on a `CollectionEntry` to include navigation propertie on the items of the collection, which does not work as expected.
For example:
```csharp
using Microsoft.EntityFrameworkCore;
A a;
using (var db = new TheDbContext())
{
db.Database.EnsureCreated();
if (!db.As.Any())
{
db.Add(new A()
{
Bs =
[
new B() { C=new() },
new B() { C=new() },
new B() { C=new() },
]
});
db.SaveChanges();
}
a = db.As.First()!;
}
JustLoadCollection(a);
LoadAndInclude(new A() { Id = a.Id });
LoadAndIncludeWhenTracked(new A() { Id = a.Id });
void JustLoadCollection(A a)
{
using var db = new TheDbContext();
db.Entry(a).Collection(a => a.Bs).Load();
Console.WriteLine(a.Bs.Count);
}
void LoadAndInclude(A a)
{
using var db = new TheDbContext();
db.Entry(a).Collection(a => a.Bs).Query().Include(b => b.C).Load();
Console.WriteLine(a.Bs.Count);
}
void LoadAndIncludeWhenTracked(A a)
{
using var db = new TheDbContext();
db.Entry(a).State = EntityState.Unchanged;
db.Entry(a).Collection(a => a.Bs).Query().Include(b => b.C).Load();
Console.WriteLine(a.Bs.Count);
}
class TheDbContext : DbContext
{
public DbSet As { set; get; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=db.sqlite");
}
}
class A
{
public Guid Id { get; set; } = Guid.NewGuid();
public ICollection Bs { get; set; } = new List();
}
class B
{
public Guid Id { get; set; } = Guid.NewGuid();
public Guid AId { set; get; }
public C C { get; set; } = null!;
}
class C
{
public Guid Id { get; set; } = Guid.NewGuid();
public Guid BId { set; get; }
public int N { set; get; }
}
```
Only `LoadAndIncludeWhenTracked` populate the collection and related data of `a`. While `JustLoadCollection` can also load the collection and `LoadAndInclude` load nothing into `a` at all.
**If I want `db.Entry(a).Collection(a => a.Bs).Query().Include(b => b.C).Load()` work, is `LoadAndIncludeWhenTracked` the proper way?**
EF Core version: 8.0.6
Database provider: Microsoft.EntityFrameworkCore.Sqlite
Target framework: .NET 8.0
Contributor guide
Assessment
This issue has not been assessed yet.