Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return entity type when using table per type inheritance

Lets say I have the following entities

public abstract class Animal
{
    public int Id {get;set;}
}

public class Cat : Animal
{
}

public class Dog : Animal
{
}

Is it possible to determine the type of entity without creating an instance.

var id = 1;
var type = context.Animals.GetTypeOfAnimal(id)

public static Type GetTypeOfAnimal(this ObjectSet<Animal> source, int id)  
{
    // What shall I do here, I dont want to fetch the instance at this point...
    var animal = source.First(a => a.Id == id);
    return animal.GetType();
}

One solution I thought about using the following method...

public static Type GetTypeOfAnimal(this ObjectSet<Animal> source, int id)  
{
    var info = source.Where(a => a.Id == id).Select(a => new {IsDog = a is Dog, IsCat = a is Cat}).First();

    if(info.IsDog) return typeof(Dog);
    if(info.IdCat) return typeof(Cat);

    return null;
}
like image 270
Rohan West Avatar asked Jun 27 '12 00:06

Rohan West


1 Answers

There is no way to get this information without query to database. You are using TPT - it means that database contains Animal, Dog and Cat tables. The inheritance in database is modeled through one-to-one relation between Animal and Dog and between Animal and Cat. The minimum what you have to do is query both Animal and Dog tables for that Id (it can exist only in one of them). The first problem is that you cannot query these tables directly with EF because EF can work only with whole entities (not only with parts mapped to single table) - you must use direct SQL. The second problem is fragility of this solution. If you add new derived entity you must fix this query (same happens for your example).

The reason why TPT queries are slow is that EF must query all inheritance tree = in your case Animal joined with Dog concatenated with Animal joined with Cat. There are some performance improvements in .NET 4.5 for querying TPT inheritance tree but it will not affect your query because it simply has to query whole structure.

like image 92
Ladislav Mrnka Avatar answered Nov 15 '22 08:11

Ladislav Mrnka