Skip to content

Support inheritance for owned/property bag/shared-type entity types #9630

Description

@ajcvickers

For example, this from #9536:

public class Friend
{
    public int Id { get; set; }
    public string Name { get; set; }

    public FullAddress Address { get; set; }
}

public class LessThanFriend
{
    public int Id { get; set; }
    public string Name { get; set; }

    public CityAddress Address { get; set; }
}

public class CityAddress
{
    public string Cap { get; set; }
    public string City { get; set; }
}

public class FullAddress : CityAddress
{
    public string Street { get; set; }
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Friend>().OwnsOne(e => e.Address);
    modelBuilder.Entity<LessThanFriend>().OwnsOne(e => e.Address);
}

This is ambiguous as to whether LessThanFriend.CityAddress should be mapped to allow inheritance such that either a CityAddress or a FullAddress could be persisted. Typically, we only map inheritance when both types are in the model. However, having both types in the model as Owned types on different entities perhaps does not have the same semantics--especially when thinking of them like complex types.

Based on triage discussion from #9536, we think we want to support both the simple mapping (just persisting given concrete type, which is what the request on #9536 is for) and the inheritance mapping, which would require, for TPH, and additional discriminator column in the table. We did not come to a final decision on which should be the default, or what the new API will look like to switch between the two.

Activity

  1. added this to the Backlog milestone on Aug 30, 2017
  2. AndriySvyryd commented on Jan 31, 2018

    @AndriySvyryd
    Member

    We would need API on ReferenceOwnershipBuilder to declare the derived types.
    Related to #10140

  3. andre-f-paggi commented on Sep 17, 2018

    @andre-f-paggi

    It took me so much time to get to this issue.

    I am having a problem in which a owned type generates a Discriminator property, even though there is no need for it, since the class that has this property is not derived anywhere else.

    Can this be the same issue?

    I tried removing it from migration and from the snapshot to test, but it generates a wrong sql statement when acessing the DbContext on that Set.

    Is there any way to get around this, without generating the property on the database?

  4. ajcvickers commented on Sep 17, 2018

    @ajcvickers
    ContributorAuthor

    @andre-f-paggi Please file a new issue and include a runnable project/solution or complete code listing that demonstrates the behavior you are seeing.

  5. chris-stormideas commented on Feb 28, 2019

    @chris-stormideas

    @ajcvickers I can look at supplying a runnable solution if it will assist getting it resolved quicker

  6. ajcvickers commented on Feb 28, 2019

    @ajcvickers
    ContributorAuthor

    @chris-stormideas We understand what this issue is about--i.e. inheritance mapping into a shared table is not supported. The feature is currently on the backlog, and not considered very high priority. The best way to influence getting it resolved is probably to make a case for why this specific mapping is so important.

  7. davidroth commented on Jan 16, 2020

    @davidroth
    Contributor

    @ajcvickers

    What about collections of owned types, where the owned-collection is polymorphic?
    For example:

    public class Order
    {
        public List<Position> Positions { get; set; } // Owned collection
    }
    
    public abstract class Position
    { }
    
    public class FancyPosition : Position
    { }
    
    public class StandardPosition : Position
    { }
    
    public class SampleContext : DbContext
    {
        public virtual DbSet<Order> Orders { get; set; }
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            modelBuilder.Entity<Order>().OwnsMany(p => p.Positions);
        }
    }

    Is this implicitly tracked by this issue or would you recommend creating a new issue for this?

  8. ajcvickers commented on Jan 16, 2020

    @ajcvickers
    ContributorAuthor

    @AndriySvyryd Thoughts on polymorphic owned collections?

  9. AndriySvyryd commented on Jan 16, 2020

    @AndriySvyryd
    Member

    Polymorphic owned collections will be covered by this, but similar to non-collections all derived types will need to be configured explicitly.

  10. digitalpowers commented on Jan 17, 2020

    @digitalpowers

    Polymorphic owned collections do provide the ability to compose our object model which is really quite nice.
    From my perspective having to define all the derived types explicitly isn't a problem at all.
    Do you guys have an idea when this issue might bubble up in the backlog?

    I have a project I have been waiting to migrate over to efcore that currently uses Horrible InHouse Awful ORM (tm) that I wrote years ago much to today me's regret. This is the only feature left that I cant really support with efcore.

  11. AndriySvyryd commented on Jan 17, 2020

    @AndriySvyryd
    Member

    @digitalpowers For now we can only say that it won't happen this year.

  12. davidroth commented on Jan 17, 2020

    @davidroth
    Contributor

    Thanks for the feedback. If polymorphic owned collections are covered by this issue, I would recommend updating the issue title+description so that users can find this. ATM it is not really clear and looks like it only covers inline owned types. Thanks!

  13. changed the title [-]Support inheritance for owned types mapped inline[/-] [+]Support inheritance for owned types[/+] on Jan 17, 2020
  14. Lobosque commented on Aug 25, 2020

    @Lobosque

    @AndriySvyryd Does this issue also cover the case where I explicitly want to set a HasDiscriminator under an owned entity?

    Example:

    
                builder.OwnsOne<AlertPattern>("Pattern", b =>
                {
                    b.HasDiscriminator<int>("type")
                        .HasValue<PatternOne>(1)
                        .HasValue<PatternTwo>(2)
                        .HasValue<PatternThree>(3)
                        .HasValue<PatternFour>(4)
                        .HasValue<PatternFive>(5);
                });
    

    In this particular example, AlertPattern is an abstract class and PatternOne and friends inherit it.

  15. 25 remaining items

  16. digitalpowers commented on Feb 29, 2024

    @digitalpowers

    is any input needed to help decide if this makes the cut for the current release? It is still the only thing preventing me from migrating to efcore and I very much want to :)

  17. chrisc-onaorg commented on Oct 4, 2024

    @chrisc-onaorg

    What's the chance we might see this in EF Core 9?

  18. ErikEJ commented on Oct 4, 2024

    @ErikEJ
    Contributor

    @chrisc-ona None - 9 is done

  19. chrisc-onaorg commented on Oct 4, 2024

    @chrisc-onaorg

    @ErikEJ well hopefully we'll have it in 10 then

  20. huberttrueselftrueme commented on Mar 13, 2025

    @huberttrueselftrueme

    Are there any updates regarding this topic ? I feel like this feature is missing so much, specially today when usage of DDD becoming more and more popular. I really looking forward to see this feature in EF core 10 !

  21. added theissue type on Jun 15, 2025
  22. ricoprzybylski commented on Feb 13, 2026

    @ricoprzybylski

    Is there any chance to see this in ef core 11 ?

  23. AndriySvyryd commented on Feb 13, 2026

    @AndriySvyryd
    Member

    @ricoprzybylski No, we are still resource constrained. I doubt this could be done before EF 13

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions