Skip to content

GetDatabaseValues for owned type throws exception if the type is only used by one entity #18366

@coder925

Description

@coder925

Calling EntityEntry.GetDatabaseValues() on an owned type can raise an exception in certain circumstances.

Steps to reproduce

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

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions