2009-07-27 2 views
8

Je suis à la recherche d'un équivalent du DataContext.GetTable<TEntity> dans Entity Framework. J'ai trouvé la méthode ObjectContext.CreateQuery<T> mais elle est différente de DataContext.GetTable<TEntity> puisqu'elle a besoin d'une chaîne de requête pour fonctionner.Entity Framework ont ​​un équivalent de DataContext.GetTable <TEntity> de Linq2Sql (ObjectContext.CreateQuery <T>?)

Existe-t-il un moyen d'obtenir un objet IQueryable pour une table en utilisant le type d'entité sans spécifier la chaîne de requête?

*EDIT: Added code snippet*
Ceci est un extrait d'une classe Repository que j'ai implémentée qui fonctionne avec linq2sql. Je ne peux pas utiliser ObjectContext.[TableName] car ce ne serait plus générique.

public class BaseRepository<TClass> : IDisposable 
     where TClass : class 
    { 
     protected BaseRepository(DataContext database) 
     { 
      _database = database; 
     } 
     ... 

     public IQueryable<TClass> GetAllEntities() 
     { 
      IQueryable<TClass> entities = _database.GetTable<TClass>(); 
      return entities; 
     } 

     public IQueryable<TClass> GetEntities(Expression<Func<TClass, bool>> condition) 
     { 
      IQueryable<TClass> table = _database.GetTable<TClass>(); 
      return table.Where(condition);  
     } 

*EDIT: Added my solution (so far..)*
C'est ce que j'utilise:

public IQueryable<TClass> GetEntities(Expression<Func<TClass, bool>> condition) 
{ 
    IQueryable<TClass> table = _database.CreateQuery<TClass>(typeof(TClass).Name); 
    return table.Where(condition);  
} 

Cela fonctionne aussi longtemps que le nom de classe est le même du nom de la table. Cela deviendra un problème pour moi lorsque je commencerai à utiliser différents objets pour la même table.

J'espère que je suis clair, merci à l'avance,
Marco :)

+0

Marco B, avez-vous trouvé une solution? J'ai le même problème et même en passant "[EntitySet]" en tant que paramètre à CreateQuery je ne peux pas le faire fonctionner. –

+2

J'ai d'abord trouvé cette réponse, et [cette réponse] (http://stackoverflow.com/questions/7263083/gettable-equivalent-for-objectcontext) après cela. Il semble que la deuxième réponse a une façon beaucoup plus facile de faire cela qui ressemble 'GetTable' de Linq2SQL –

Répondre

6

En fait, le concepteur EF utilise lui-même CreateQuery avec des chaînes codées en dur pour les références statiques. Si vous creusez dans le fichier de concepteur, vous verrez quelque chose comme ceci:

public global::System.Data.Objects.ObjectQuery<Customers> Customers 
{ 
    get 
    { 
     if ((this._Customers == null)) 
     { 
      this._Customers = base.CreateQuery<Customers>("[Customers]"); 
     } 
     return this._Customers; 
    } 
} 

private global::System.Data.Objects.ObjectQuery<Customers> _Customers; 

Techniquement, il n'y a pas de solution parfaite, car vous pouvez utiliser le même type d'entité pour les jeux d'entités différentes. Mais vous pouvez lui donner l'ancien essai de collège:

public IQueryable<TEntity> GetEntities<TEntity>() 
{ 
    Type t = typeof(TEntity); 
    var edmAttr = (EdmEntityTypeAttribute)Attribute.GetCustomAttribute(t, 
     typeof(EdmEntityTypeAttribute), false); 
    if (edmAttr == null) // Fall back to the naive way 
    { 
     return context.CreateQuery<TEntity>(t.Name); 
    } 
    var ec = context.MetadataWorkspace.GetEntityContainer(
     context.DefaultContainerName, DataSpace.CSpace); 
    var entityType = context.MetadataWorkspace.GetType(edmAttr.Name, 
     edmAttr.NamespaceName, DataSpace.CSpace); 
    var es = ec.BaseEntitySets.First(es => es.ElementType == entityType); 
    return context.CreateQuery<TEntity>(es.Name); 
} 
+0

Merci ça fonctionne bien! Par chance, j'ai trouvé une solution similaire dans le projet kigg sur codeplex (http://kigg.codeplex.com). – marcob

+0

Essayez d'utiliser ce code, mais le problème est que BaseEntitySets.First n'est pas IQueryable, donc je ne vois pas comment les autres ont pu faire fonctionner cet exemple. –

+0

Je pense que cette question a besoin d'être mise à jour. Il semble que la personne qui a posé la question ait accepté une réponse dont il n'utilise qu'une partie, de sorte que la réponse prête à confusion.En réalité, le questionneur n'utilise que le contexte de retour.CreateQuery (t.Name); 'code que je n'ai pas remarqué et passé quelques heures à essayer de faire fonctionner la réponse acceptée. Dès que je suis passé à l'utilisation de la méthode CreateQuery, cela fonctionne parfaitement. –

0

J'espère que je ne manque point, mais serait-il pas:

ObjectContext.TableName 

Où TableName est l'EntitySet du type avec lequel vous voulez travailler.

+0

Salut, je ne veux pas utiliser le nom de la table parce que je veux avoir un moyen générique d'accéder à la table. J'ai ajouté un extrait de code de ma classe pour mieux expliquer ce que j'aimerais obtenir. La seule solution que je peux imaginer maintenant est d'utiliser la méthode ObjectContext.CreateQuery en changeant un peu la structure de ma classe générique en passant au constructeur aussi le TableName. – marcob

1
public IQueryable GetTable<T>(T entity) where T : class 
{ 
    return context.CreateObjectSet<T>(); 
} 
Questions connexes