-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Loading entity from DB does not properly load owned entities (In memory provider) #23687
Comments
Note for triage: I am able to reproduce this; it looks like Includes for owned collections are not working here with in the in-memory database. Adding the Includes explicitly doesn't help, so it doesn't look like it's an issue with auto-includes specifically. Verified that the same thing works with SQL Server. |
Makes me question if data is getting saved correctly in the InMemoryTables. |
@smitpatel Could be--I didn't check that. |
I have a similar issue with my use case reproduced in the sample below. Querying on the owned type isn't returning the expected result. I only have the issue with InMemoryDatabase and not with SQL provider. When removing the composite primary key it's working as expected. using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace EFCoreTrackedIssue
{
class Program
{
static void Main(string[] args)
{
const int id2 = 1;
using (var dbContext = new ExampleContext())
{
var aggregateRoot = new AnAggregateRoot
{
Id2 = id2,
AProp = "Test",
OwnedDependent = new OwnedDependent
{
HasEnded = false
}
};
dbContext.AggregateRoots.Add(aggregateRoot);
dbContext.SaveChanges();
}
using (var dbContext = new ExampleContext())
{
var test1 = dbContext.AggregateRoots.Include(x => x.OwnedDependent).Where(x => x.Id2 == id2).ToArray();
Console.WriteLine("Test1 Count: {0}", test1.Length); // Output: Test1 Count: 1
Console.WriteLine("Value OwnedDependent: {0}", test1.Single().OwnedDependent); // Output: Value OwnedDependent: 'null' => expects instance
var test2 = dbContext.AggregateRoots.Include(x => x.OwnedDependent).Where(x => x.Id2 == id2 && x.OwnedDependent.HasEnded == false).ToArray();
Console.Write("Test2 Count: {0}", test2.Length); // Output: Test2 Count: 0 => expects 1
}
Console.ReadLine();
}
public class ExampleContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseInMemoryDatabase("MyTest");
public DbSet<AnAggregateRoot> AggregateRoots { get; set; }
protected override void OnModelCreating(ModelBuilder mb)
{
base.OnModelCreating(mb);
mb.Entity<AnAggregateRoot>().HasKey(e => new{e.Id1, e.Id2});
mb.Entity<AnAggregateRoot>().Property(e => e.Id1).ValueGeneratedOnAdd();
mb.Entity<AnAggregateRoot>().Property(e => e.Id2).ValueGeneratedNever();
mb.Entity<AnAggregateRoot>().OwnsOne(e => e.OwnedDependent);
}
}
}
public class AnAggregateRoot
{
public int Id1 { get; set; }
public int Id2 { get; set; }
public string AProp { get; set; }
public OwnedDependent OwnedDependent{ get; set; }
}
public class OwnedDependent
{
public bool HasEnded { get; set; }
}
} |
I am also facing a similar issue with EF SqlServer 5.0.1. I have a Parent type with a child owned type, and the child owned type has a collection of owned types public class ResourceType
{
public int Id { get; set; }
public ChildType Child { get; set; }
}
[Owned]
public class ChildType
{
public string Text { get; set; }
public ICollection<GrandchildType> Grandchildren { get; set; }
}
[Owned]
public class GrandchildType
{
public string Value { get; set; }
}
int id1, id2;
using (var dbContext = new TestDbContext())
{
var resource1 = new ResourceType
{
Child = new ChildType
{
Text = "hello",
Grandchildren = new List<GrandchildType>
{
new GrandchildType{ Value= "hello" }
}
}
};
var resource2 = new ResourceType
{
Child = new ChildType
{
Text = null,
Grandchildren = new List<GrandchildType>
{
new GrandchildType{ Value= "hello" }
}
}
};
dbContext.Resources.AddRange(resource1, resource2);
await dbContext.SaveChangesAsync();
id1 = resource1.Id;
id2 = resource2.Id;
}
using (var dbContext = new TestDbContext())
{
var resource1 = await dbContext.Resources.SingleOrDefaultAsync(x => x.Id == id1);
var resource2 = await dbContext.Resources.SingleOrDefaultAsync(x => x.Id == id2);
if (resource1.Child == null)
{
Console.WriteLine("Child missing from resource 1");
}
else if (resource2.Child == null)
{
Console.WriteLine("Child missing from resource 2");
}
else
{
Console.WriteLine("All ok");
}
}
public class TestDbContext : DbContext
{
public TestDbContext()
: base(new DbContextOptionsBuilder<TestDbContext>()
.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Database=TestOwnedType;Trusted_Connection=True;MultipleActiveResultSets=true")
.Options) { Database.EnsureCreated(); }
public DbSet<ResourceType> Resources { get; set; }
} |
/cc @smitpatel |
Regression introduced in 58a07b6 CreateKeyValueReadExpression used to inject anonymous object struct. Which made comparison happen correctly between owned reference navigation. We removed it in 5.0 so now it is 2 object[] instances which never matches. This code path is only hit for composite key scenario. @almostchristian - Your issue is different. This issue only happens for InMemory provider. You are using SqlServer provider. See #23198 (comment) |
Resolves #23687 Composite key selector needs wrapper so that we compare them component-wise
Ran into the same issue when upgrading to 5.0.1 from 3.1.6; some of my unit-tests failed. Any ETA on 5.0.3? |
Similar issue but with SQL Server Provider: #24165 |
Description
When loading a entity from the DB, some owned entities are not loaded when using the InMemory provider. This does only occur with the InMemory provider. In the code sample below you can find that line:
device.DistributorAssignments.First().CustomerId
results innull
Expected Behaviour:
device.DistributorAssignments.First().CustomerId
should not benull
but be loaded correctly.Code to reproduce
Provider and version information
EF Core version: 5.0.1
Database provider: Microsoft.EntityFrameworkCore.InMemory 5.0.1
Target framework: NET 5.0
Operating system: Win 10
IDE: Visual Studio 2019 16.8.3
The text was updated successfully, but these errors were encountered: