Search code examples
c#mysql.netentity-frameworktph

Find out type with primary key given in Entity Framework using TPH


I have the following scenario:

public abstract class Account
{
    public Guid PKey { get; set; } = Guid.NewGuid();    
    public string Owner { get; set; }
}

public class CheckingAccount : Account
{
    public int Fee { get; set; }
}

public class SavingAccount : Account
{
    public double InterestRate { get; set; }
}

I am using Entity Framework with Table per Hierarchy, so that there will be a single table in the database that holds both CheckingAccount-Records and SavingAccount-Records and this table will contain a column named Discriminator, which is filled with the value "CheckingAccount" or "SavingAccount" respectively.

Now I want to take a primary key (Guid) as my input and find out the type of the record this primary key belongs to.

I have a given Guid and want to find out if the record for this Guid is a CheckingAccount-Record or a SavingAccount-Record.

I tried something like this:

using(MyContext ctx = new Context())
{
    CheckingAccount ca = ctx.CheckingAccount.Find(pKey);
    SavingAccount sa = ctx.SavingAccount.Find(pKey);

    if(ca != null)
    {
        Console.WriteLine("It's a CheckingAccount!");
    }
    else if(sa != null)
    {
        Console.WriteLine("It's a SavingAccount!");
    }
}

However, this results in an InvalidOperationException: When the record is a SavingAccount, it will say

"The entity found was of type SavingAccount when an entity of type CheckingAccount was requested."

when I call the first Find() method.

How can I find out the type given only the primary key and the two types that it could belong to?


Solution

  • You can use EF polymorphic queries through base entity DbSet. Something like this should do the job:

    var account = ctx.Set<Account>().Find(pKey);
    if(account is CheckingAccount)
    {
        Console.WriteLine("It's a CheckingAccount!");
    }
    else if (account is SavingAccount)
    {
        Console.WriteLine("It's a SavingAccount!");
    }