2012-06-27 10 views
7

Diciamo che ho le seguenti entitàritorno tipo di entità quando si utilizza tabella per ogni tipo di ereditarietà

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

public class Cat : Animal 
{ 
} 

public class Dog : Animal 
{ 
} 

E 'possibile determinare il tipo di entità senza creare un'istanza.

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 soluzione che ho pensato di usare il metodo seguente ...

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

Non penso che tu possa. – Yeonho

+0

Anche il design odora un po '; interrogare il sottotipo specifico di un tipo generico e quindi ramificarlo che dovrebbe essere probabilmente sostituito con il polimorfismo. – millimoose

+0

Al punto del tuo commento, la fonte è già stata recuperata. È questo che stai cercando di prevenire? EDIT: No ora vedo. Tempo di pensare ora – Michael

risposta

2

Non v'è alcun modo per ottenere queste informazioni senza query di database. Stai usando TPT - significa che il database contiene tabelle di animali, cani e gatti. L'ereditarietà nel database è modellata attraverso la relazione uno a uno tra animale e cane e tra animale e gatto. Il minimo di ciò che devi fare è interrogare le tabelle Animale e Cane per quell'Id (può esistere solo in una di esse). Il primo problema è che non è possibile interrogare queste tabelle direttamente con EF perché EF può funzionare solo con intere entità (non solo con parti mappate su una singola tabella) - è necessario utilizzare l'SQL diretto. Il secondo problema è la fragilità di questa soluzione. Se aggiungi una nuova entità derivata, devi risolvere questa query (lo stesso accade per il tuo esempio).

Il motivo per cui le query TPT sono lenti EF è che deve interrogare tutti albero di ereditarietà = nel tuo caso Animal unito con Dog concatenato con Animal unito con Cat. Ci sono alcuni miglioramenti delle prestazioni in .NET 4.5 per l'interrogazione dell'albero di ereditarietà di TPT, ma non influenzerà la tua query perché deve semplicemente interrogare l'intera struttura.

+0

Solo per curiosità: puoi evitare questa penalità usando una proiezione che usa solo le proprietà definite in "Animale"? – millimoose

Problemi correlati