2012-06-27 9 views
7

Digamos que tengo las siguientes entidadestipo de entidad cuando se utiliza la tabla según el tipo de herencia

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

public class Cat : Animal 
{ 
} 

public class Dog : Animal 
{ 
} 

¿Es posible determinar el tipo de entidad sin crear una instancia.

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(); 
} 

Una solución Pensé en usar el siguiente método ...

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; 
} 
+1

No creo que puedas. – Yeonho

+0

El diseño también huele un poco; consultar el subtipo específico de un tipo genérico y luego bifurcarlo que probablemente debería reemplazarse por polimorfismo. – millimoose

+0

En el momento de su comentario, la fuente ya ha sido captada. ¿Es eso lo que estás tratando de prevenir? EDITAR: No, ahora veo. Pensando en el tiempo ahora. – Michael

Respuesta

2

No hay manera de obtener esta información sin consulta a la base de datos. Está utilizando TPT: significa que la base de datos contiene tablas de animales, perros y gatos. La herencia en la base de datos se modela a través de la relación uno-a-uno entre Animal y Perro y entre Animal y Gato. Lo mínimo que tienes que hacer es consultar las tablas Animal y Dog para ese ID (puede existir solo en una de ellas). El primer problema es que no puede consultar estas tablas directamente con EF porque EF solo puede trabajar con entidades completas (no solo con partes asignadas a una sola tabla): debe usar SQL directo. El segundo problema es la fragilidad de esta solución. Si agrega una nueva entidad derivada, debe corregir esta consulta (lo mismo ocurre con su ejemplo).

La razón por la cual las consultas TPT son lentos es que EF debe consultar todas árbol de herencia = en su caso Animal unido a Dog concatenado con Animal se unieron a Cat. Hay algunas mejoras de rendimiento en .NET 4.5 para consultar el árbol de herencia TPT, pero no afectará su consulta porque simplemente tiene que consultar toda la estructura.

+0

Solo por curiosidad: ¿puedes evitar esta penalización usando una proyección que solo hace uso de las propiedades definidas en 'Animal'? – millimoose

Cuestiones relacionadas