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

No result returned when using Include and there is an Owned Entity in the object graph #26157

Closed
t-dambacher opened this issue Sep 23, 2021 · 7 comments · Fixed by #26213
Closed
Assignees
Labels
area-in-memory area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-bug
Milestone

Comments

@t-dambacher
Copy link

Hello,

We are having some trouble when upgrading an existing .NET 5 app to .NET 6. Our test suit, which relies a bit on the InMemory provider, fails since upgrading to .NET 6, on really simple EF queries.

Our test case do basically something like this:

context.Add(new Foo());
await context.SaveChangesAsync();

Foo? foo = await context.Set<Foo>().Include(f => f.Bar).FirstOrDefaultAsync();
bool isNull = foo is null; // false with EFCore 5, true with EFCore 6

Those queries were returning a result before, but won't now. I achieved to isolate the first version where the problem occures, and it all starts with the 6.0-preview3 version of the InMemory provider. Everything works with version 6.0-preview2 or .NET 5; there is another issue with version 6.0-preview1 but it doesn't seem related and was fixed afterwards.

Initially, I thought that it was linked to an old issue, #9470, but the navigation property is nullable here.

After digging a bit, it seems to stem from the fact that we have some owned entity in the mapping, and we use the InMemory provider. If I either remove the owned entity or use a real database (with the SqlServer provider), our test suit passes without an issue (and this is what I'll do for now).

Include your code

I've attached a little repro project that can be used. It's an MSTest project with a standard test case.

Include provider and version information

EF Core version: starting from v6.0 preview 3 but still exists in v6.0 RC 1
Database provider: Microsoft.EntityFrameworkCore.InMemory
Target framework: .NET 6.0 RC1
Operating system: Windows 10 Enterprise, version 2004, build 19041.1237, although it doesn't seem related.
IDE: Visual Studio 2022 17.0 Preview 4.1

@ajcvickers
Copy link
Contributor

Note for triage: this is a NRT issue, possibly coupled with changes to optional/required dependents. Baz is owned. When the navigation is non-nullable, the parent is not returned. When it is nullable, the parent is returned.

public class Bar
{
    public long Id { get; set; }

    public long FooId { get; set; }
    public virtual Foo Foo { get; set; } = null!;

    // public virtual Baz? Baz { get; set; } = new(); // Works
    public virtual Baz Baz { get; set; } = new(); // Doesn't work
}

public class Baz
{ }

public class Foo
{
    public long Id { get; set; }
    public virtual Bar? Bar { get; set; }
}

@roji
Copy link
Member

roji commented Sep 24, 2021

@ajcvickers is it reproducible by playing around with the property's requiredness via the Fluent API? Just to isolate the NRT aspect....

@ajcvickers
Copy link
Contributor

This is not down to NRTs directly, but rather whether or not the navigation to the owned type is configured as required or not. Making it explicitly required results in the same behavior:

            builder.OwnsOne(t => t.Baz, e => { });
            builder.Navigation(e => e.Baz).IsRequired();

/cc @smitpatel

@smitpatel
Copy link
Contributor

smitpatel commented Sep 28, 2021

While the "owned type" is required, it does not contain any properties to distinguish if the instance exists or not. Hence even though an instance of "baz" was "saved" to database, there is no way to query it back. This is by-design. Refer to #23564

@t-dambacher
Copy link
Author

My bad, I used a too simple example here. If I add a required property:

public class Baz
{ 
    public string Name { get; set; } = string.Empty;
}

And the mapping then becomes:

builder.OwnsOne(t => t.Baz, e => 
{
    e.Property(t => t.Name).HasColumnName("nom").IsRequired();
});

The issue still occures, and nothing is returned from the db.

@smitpatel
Copy link
Contributor

This is required dependent so it should always materialize. Need to check if relational model built is correct for this scenario. Query shouldn't be doing anything fancy.

@ajcvickers ajcvickers added this to the 6.0.0 milestone Sep 29, 2021
smitpatel added a commit that referenced this issue Sep 29, 2021
We did optimization that required dependent can generate join rather than left join but that is dependent if the owner is nullable or not.

Resolves #26157
@smitpatel smitpatel added area-in-memory closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. labels Sep 29, 2021
@smitpatel
Copy link
Contributor

"In-Memory" bug. 🤦🏻

smitpatel added a commit that referenced this issue Sep 30, 2021
We did optimization that required dependent can generate join rather than left join but that is dependent if the owner is nullable or not.

Resolves #26157
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-in-memory area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants