1

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?

Danghor
  • 17
  • 2
  • 7

2 Answers2

3

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!");
}
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
  • 1
    Yep, that worked! Thank You! Unfortunately, my upvote is not visible, since my reputation is too low. – Danghor Jan 16 '18 at 22:14
0

Have you tried using var or object as the type for ca and sa?

Give this a try:

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

    if(ca is CheckingAccount)
    {
        Console.WriteLine("It's a CheckingAccount!");
    }
    else if(sa is SavingAccount)
    {
        Console.WriteLine("It's a SavingAccount!");
    }
}
mrtig
  • 2,217
  • 16
  • 26
  • Unfortunately, this does not work either. The Find()-Method itself throws the exception, even before assigning the result to a variable. – Danghor Jan 16 '18 at 21:41
  • Do these types come from different sql tables? – mrtig Jan 16 '18 at 21:55
  • No, all records are stored in a single table named "Account". The table contains a column named "Discriminator". In this column, the name of the type ("CheckingAccount" or "SavingAccount") is stored automatically when saving new records. – Danghor Jan 16 '18 at 22:11