Mike Burton
Mike Burton

Reputation: 3020

How can I ignore an FK defined in a base type when using TPT in EF Core

I have an Entity Framework Core model defined as follows:

class User
{
    public int ID;
    public ICollection<Foo> OwnedFoos;
}

[PrimaryKey(nameof(ID), nameof(OwnerID))]
class Foo
{
    public int ID;
    public int OwnerID;

    [ForeignKey("OwnerID")]
    public User Owner;
}

class DerivedFoo : Foo
{
    public int DerivedProp;
}

This generates a schema roughly as follows (SQL pseudocode):

TABLE Users
COLUMN ID

TABLE Foos
COLUMN ID
COLUMN OwnerID
PRIMARY KEY (ID, OwnerID)
FOREIGN KEY OwnerID -> User.ID ON CASCADE DELETE

TABLE DerivedFoos
COLUMN ID
COLUMN OwnerID
COLUMN DerivedProp
FOREIGN KEY OwnerID -> Users.ID ON CASCADE DELETE
FOREIGN KEY (ID, OwnerID) -> (Foos.ID, Foos.OwnerID) ON CASCADE DELETE

This causes an error when I try to generate the database in SQL Server because it contains multiple paths for a cascade delete. I can remove the derived->base CASCADE DELETE clause using fluent API, but what I'd really like to do is modify the schema to be the following by removing the Users FK from just the derived type table.

TABLE Users
COLUMN ID

TABLE Foos
COLUMN ID
COLUMN OwnerID
PRIMARY KEY (ID, OwnerID)
FOREIGN KEY OwnerID -> User.ID ON CASCADE DELETE

TABLE DerivedFoos
COLUMN ID
COLUMN OwnerID
COLUMN DerivedProp
FOREIGN KEY (ID, OwnerID) -> (Foos.ID, Foos.OwnerID) ON CASCADE DELETE

When I try to use Ignore() to remove this relationship, however, the EF tools throw an error because the relationship is defined on the base type. Is there any way to achieve the desired schema without manual intervention?

Upvotes: 0

Views: 29

Answers (1)

Kevin UI
Kevin UI

Reputation: 292

If you use FluentAPI, you can do something similar to this. I think it's more challenging with Data Annotations. You may have to write custom SQL for it.

{
    modelBuilder.Entity<DerivedFoo>()
        .HasMany(p => p.User)
        .OnDelete(DeleteBehavior.Restrict);  // This turns off cascade delete
}

Upvotes: 0

Related Questions