-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
Calling EntityEntry.GetDatabaseValues()
on an owned type can raise an exception in certain circumstances.
Steps to reproduce
- Run this simplified project that is only using the Order and ShipmentAddress entities:
https://github.com/coder925/EntityFramework.Docs/tree/owned-type-issue/samples/core/Modeling/OwnedEntities
Expected result: Only the changed properties of the owned entity is saved.
Actual result: An exception:
System.InvalidOperationException
HResult=0x80131509
Message=Cannot create a DbSet for 'StreetAddress' because it is configured as an owned entity type and should be accessed through the defining entities.
Source=Microsoft.EntityFrameworkCore
StackTrace:
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityType()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.CheckState()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityQueryable()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Linq.IQueryable.get_Provider()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsNoTracking[TEntity](IQueryable`1 source)
at Microsoft.EntityFrameworkCore.Internal.EntityFinder`1.GetDatabaseValuesQuery(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.Internal.EntityFinder`1.GetDatabaseValues(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry.GetDatabaseValues()
at EFModeling.OwnedEntities.Program.Main(String[] args) in C:\repos-github\EntityFramework.Docs\samples\core\Modeling\OwnedEntities\Program.cs:line 46
Workaround:
Uncomment code in OwnedEntityContext:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
#region OwnsOne
modelBuilder.Entity<Order>().OwnsOne(p => p.ShippingAddress);
#endregion
// Uncomment following line and it starts working
#region OwnsOne
//// modelBuilder.Entity<Order2>().OwnsOne(p => p.ShippingAddress);
#endregion
}
It seems if more than one Entity is owning ShipmentAddress the excpetion is not occuring.
Use case
I am receiving a detached Order entity that needs to be updated in the database. However, I am only allowed to save actual changed properties and cannot use context.Update(order)
.
Instead, I use this read-update pattern:
var orderEntry = context.Attach(order);
orderEntry.OriginalValues.SetValues(orderEntry.GetDatabaseValues());
and for each owned type owned by Order (i.e. value objects):
var shippingAddressEntry = context.Entry(order.ShippingAddress);
shippingAddressEntry.OriginalValues.SetValues(shippingAddressEntry.GetDatabaseValues());
Further technical details
EF Core version: 3.0.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET Core 3.0
Operating system: Windows 10 Enterprise
IDE: Visual Studio 2019 16.3.0