Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ef core created an instance for each element in a one to many relationship with the same foreign key #21208

Closed
dpr-dev opened this issue Jun 10, 2020 · 8 comments
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported

Comments

@dpr-dev
Copy link

dpr-dev commented Jun 10, 2020

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(); /

Further technical details

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" /> 
@dpr-dev
Copy link
Author

dpr-dev commented Jun 10, 2020

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(); 

@smitpatel
Copy link
Contributor

No tracking query does not perform identity resolution. See https://docs.microsoft.com/en-us/ef/core/querying/tracking#identity-resolution

Also see #19877

@dpr-dev
Copy link
Author

dpr-dev commented Jun 10, 2020

@smitpatel, Without .AsNoTracking does not work either. that was the first thing I checked

@smitpatel
Copy link
Contributor

@dpr-dev - Please provide a runnable repro code.

@tiesont
Copy link

tiesont commented Jun 17, 2020

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).

@smitpatel
Copy link
Contributor

@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.

@tiesont
Copy link

tiesont commented Jun 17, 2020

@smitpatel I assume that means that there is no way to mimic that behavior, now?

@smitpatel
Copy link
Contributor

The only way to do that now is to initialize new DbContext to run the query and then throw away the context.

@ajcvickers ajcvickers added the closed-no-further-action The issue is closed and no further action is planned. label Jun 22, 2020
@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported
Projects
None yet
Development

No branches or pull requests

4 participants