Skip to content
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

Allow mapping different entity types in a hierarchy to different store constructs (table/view/procedure/etc.) #27192

Open
Tracked by #22953
cjalex1313 opened this issue Jan 14, 2022 · 6 comments

Comments

@cjalex1313
Copy link

TPT inheritance with views:

Pretty plain question, I didn't find documentation about this nor did what I tried work.

@ajcvickers
Copy link
Member

@cjalex1313 Yes. What did you try and it what way did it fail?

@cjalex1313
Copy link
Author

I just tried again in an example web api proj.

Database structure:
CREATE TABLE Animal (
ID UNIQUEIDENTIFIER PRIMARY KEY,
[Type] INT NOT NULL DEFAULT 0,
[DogName] NVARCHAR(MAX) NULL,
[CatName] NVARCHAR(MAX) NULL
)

CREATE VIEW Dog as
SELECT
ID,
DogName as Name
from dbo.Animal where [Type] = 1

CREATE VIEW Cat as
SELECT
ID,
CatName as Name
from dbo.Animal where [Type] = 2


DTO Classes

public class Animal
{
    public Guid ID { get; set; }
}

public class Dog : Animal
{
    public string Name { get; set; }
}

public class Cat : Animal
{
    public string Name { get; set; }
}

EF Context

public class AnimalContext : DbContext
{
    public DbSet<Animal> Animals { get; set; }
    public DbSet<Dog> Dogs { get; set; }
    public DbSet<Cat> Cats { get; set; }

    public AnimalContext(DbContextOptions<AnimalContext> options)
: base(options)
    { }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Animal>(e =>
        {
            e.ToTable("Animal");
            e.HasKey("ID");
        });
        modelBuilder.Entity<Dog>(e =>
        {
            e.ToView("Dog");
            e.Property(d => d.Name).HasColumnName("Name");
        });
        modelBuilder.Entity<Cat>(e =>
        {
            e.ToView("Cat");
            e.Property(d => d.Name).HasColumnName("Name");
        });
    }
}

By querying anything from the context I'm getting a error message of this type:

System.InvalidOperationException: Both 'Cat' and 'Animal' are mapped to the table 'Animal'. All the entity types in a hierarchy that don't have a discriminator must be mapped to different tables. See https://go.microsoft.com/fwlink/?linkid=2130430 for more information.

@smitpatel
Copy link
Member

e.ToTable("Animal");

You are mapping Animal to table and derived types to view. Either map all of them to view or all of them to table.

@cjalex1313
Copy link
Author

Ok.. well, that's not an option for me unfortunately

@cjalex1313
Copy link
Author

In anycase thanks for the info. Much appreciated

@AndriySvyryd AndriySvyryd self-assigned this Jan 19, 2022
@AndriySvyryd
Copy link
Member

AndriySvyryd commented Jan 19, 2022

Ok.. well, that's not an option for me unfortunately

You can map all types using ToTable even if they are views in the database. The difference is mostly in how Migrations behave, which I assume you don't use.

Alternatively, calling ToTable(null) as well on derived types might make this work.

@ajcvickers ajcvickers added this to the Backlog milestone Jan 22, 2022
@ajcvickers ajcvickers changed the title Is efcore inheritance (TPT) supported if the entities are being mapped to views? Allow mapping different entity types in a hierarchy to different store constructs (table/view/procedure/etc.) Jan 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment