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;
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With