dotnet/efcore

How to map in EF Core 6 a vlue object with derive classes?

ComptonAlvaro opened this issue · 1 comments

I have a Order and a OrderState classes, but I will implement state pattern, so I will have a base class State and derived classes for each state.

The classes would be this:

class Order
{
    long Id;

    Status State;
}

class Status
{
    string abstract State;

    public abstract void Method1();
}

class Status1 : Status
{
    public Status1()
    {
        State = "Status1";

        public ovderride Method1()
        {
            //do something
        }
    }

    stirng override State;
}


class Status2 : Status
{
    public Status1()
    {
        State = "Status2";
    }

    stirng override State;

    public override void Method1()
        {
            //do something
        }
}

In EF Core, I have a class to configure Order with fluent API:

paramPedidoCompraConfiguracion
    .OwnsOne(miOrder => miOrder.State, stateNavigationBuilder =>
    {
        sateNavigationBuilder.WithOwner();

        stateNavigationBuilder.Property<string>(x => x.State)
            .HasColumnName("State")
            .HasColumnType("varchar(200)")
            .IsRequired()
            .IsUnicode(false)
            .HasMaxLength(200);
    });

But I get this error: The corresponding CLR type for entity type 'Status' cannot be instantiated, and there is no derived entity type in the model that corresponds to a concrete CLR type.

I have read the documentation about this in Microsoft docs: https://learn.microsoft.com/en-us/ef/core/modeling/inheritance, in particular in the shared columns, because I want to share the column to avoid to have one column for each state.

This is the code in the documentation:

public class MyContext : DbContext
{
    public DbSet<BlogBase> Blogs { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .Property(b => b.Url)
            .HasColumnName("Url");

        modelBuilder.Entity<RssBlog>()
            .Property(b => b.Url)
            .HasColumnName("Url");
    }
}

public abstract class BlogBase
{
    public int BlogId { get; set; }
}

public class Blog : BlogBase
{
    public string Url { get; set; }
}

public class RssBlog : BlogBase
{
    public string Url { get; set; }
}

It is definying a dbSet for the base blog, but in my case I am using the state as value object, not as identity, so if I am not wrong, I shouldn't to create a dbSet for values objects, only for entities. So if it is correct, I don't know how to configure my value object with derived classes.

How could I do it?

Thanks.

Duplicate of #9630.