Hi. I have a two classes
class Road
{
// only for ef
private Road() { Debug.WriteLine("Road entity created"); }
public Road(...) {}
public IReadOnlyList<Statement> Statements {get; private set;}
}
class Statement
{
// only for ef
private Statement() {}
public Statement(...) {}
public Road Road {get; private set;}
}
This query created many instances for the parent entity (Road) with the same foreign key. as a result, I got a million identical roads (instead of one)
List<Statement> items = await _context.Statements
.AsNoTracking().Include(e => e.Road)
.Where(e => statements.Contains(e.Id)).ToListAsync(); /
Operating system: Windows
Packages:
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="3.1.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.2"/>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.4" />
but this fork's without duplications. Each roads (r) contains many statements
var query = from s in _context.Statements.Where(s => ids.Contains(s.Id))
join r in _context.Roads
on s.RoadId equals r.Id
select new { s, r };
var queryResult = query.ToList();
No tracking query does not perform identity resolution. See https://docs.microsoft.com/en-us/ef/core/querying/tracking#identity-resolution
Also see #19877
@smitpatel, Without .AsNoTracking does not work either. that was the first thing I checked
@dpr-dev - Please provide a runnable repro code.
So, it seems like our two choices are:
1) Leave change tracking enabled --> get expected values in navigation properties
2) Disable change tracking --> get duplicate values in navigation properties.
Is there a way to enforce/approximate the weak references mentioned at the end of the linked doc above? Everything I read says to disable change tracking on read-only queries to help return results faster, but nothing mentions this behavior (granted, most of those articles were for EF Core 2.x).
@tiesont - Starting with EF Core preview5 new API is added. It is called PerformIdentityResolution (beware this will be renamed in preview7 to AsNoTrackingWithIdentityResolution`.
That will use a stand alone state manager to de-dupe results but not track them.
@smitpatel I assume that means that there is no way to mimic that behavior, now?
The only way to do that now is to initialize new DbContext to run the query and then throw away the context.