Sto utilizzando Entity Framework con un database di grandi dimensioni (composto da più di 200 tabelle).Metodo generico per recuperare DbSet <T> da DbContext
Cercando di creare un metodo generico che restituisce il DbSet<T>
di un'apposita tabella T
(cioè classe, che può essere TableA
).
La classe entità che era (automaticamente) creati utilizzando il modello di dati dell'entità assomiglia così:
public partial class sqlEntities : DbContext
{
public virtual DbSet<TableA> TableA { get; set; }
public virtual DbSet<TableB> TableB { get; set; }
public virtual DbSet<TableC> TableC { get; set; }
... // other methods
}
La mia classe principale è come questo
public class TableModifier
{
// Should return first 10 elements from a table of that type T
public IQueryable<T> GetFromDatabase<T>() where T : EntityObject
{
try
{
using (sqlEntities ctx = new sqlEntities())
{
// Get the DbSet of the type T from the entities model (i.e. DB)
DbSet<T> dbSet = ctx.Set<T>();
return dbSet.Take(10);
}
}
catch (Exception ex)
{
// Invalid type was provided (i.e. table does not exist in database)
throw new ArgumentException("Invalid Entity", ex);
}
}
... // other methods
}
devo impostare un vincolo where T : EntityObject
su T
per rientrare nei limiti EntityObject
. Se non ci fosse un tale vincolo allora il DbSet<T> dbSet
si lamenterebbe (ad esempio T deve essere un tipo di riferimento) che potrebbe ottenere più del previsto in termini di tipi (based su questo).
Il problema si verifica quando provo a chiamare effettivamente il metodo con un tipo specifico.
[TestMethod]
public void Test_GetTest()
{
TableModifier t_modifier = new TableModifier();
// The get method now only accepts types of type EntityObject
IQueryable<TableA> i_q = t_modifier.GetFromDatabase<TableA>();
}
dà un errore:
There is no implicit reference conversion from 'TableMod.TableA' to
'System.Data.Entity.Core.Objects.DataClasses.EntityObject'.
Come posso (cast?) Il tipo TableA
come EntityObject
se so che esiste per quel modello entità?
anche se questo è sintassi non corretta (e la logica) questo è quello che sto cercando:
t_modifier.GetFromDatabase<(EntityObject)TableA>();
Come posso definire il TableA
(insieme a tutti gli altri 200 tabelle) tipo ad essere una parte di EntityObject
?
Una possibile soluzione
Attiva il mio vincolo era troppo specifico, tutto quello che dovevo cambiare stato da where T : IEntity
a
where T : class
Così il T
è ciò che il DbSet<T>
inizialmente previsto, un tipo di classe
Salva il problema di havin g aggiungere implementazioni alle classi tabella 200+, TableA
, TableB
...
Poi naturalmente ci sono altri problemi come la modifica del tipo di ritorno da IQueryable<T>
al List<T>
poiché il IQueryable
sarebbero altrimenti restituiti al di fuori del campo di applicazione DbContext
(es sqlEntities
) rendendolo inutile.
Che cosa vuoi testare? –
Supponendo che 'TableMod.TableA' non erediti da' EntityObject'? – DavidG
Probabilmente stai prendendo di mira una versione di EF che non richiede più che tutti i tipi di entità derivino da "EntityObject". Usando 'dove T: class' sarà sufficiente per i tuoi scopi. Non è necessario modificare la mappa di ereditarietà sui tipi esistenti solo per adattarsi a questo * nuovo * metodo che si sta scrivendo. –