2010-09-22 4 views
0

En utilisant SubSonic3, j'ai cette méthode générique (merci à Guy LINQ, James Curran):SubSonic Comment fournir un nom de colonne dans une méthode générique

public List<T> GetFromList<T>(List<Guid> _IDs, 
     Func<T, Guid> GetID, 
     Func<IQueryable<T>> GetAll) 
      where T : class, IActiveRecord 
    { 
     List<T> rc = null; 
     var Results = 
      from item in GetAll() 
      where (_IDs as IEnumerable<Guid>).Contains(GetID(item)) 
      select item; 

     rc = Results.ToList<T>(); 
     return rc; 
    } 

Il est appelé avec quelque chose comme

List<Job> jresults = GetFromList(IDList, 
    item => item.JobID, 
    () => Job.All()); 

Où IDList est une liste de guids qui sont des clés de la table. Lorsqu'il n'est pas générique, le linq ressemble à ceci et fonctionne parfaitement. J'ai été très impressionné que le fournisseur de LINQ de SubSonic pourrait prendre ce code et la transformer en SELECT * FROM emploi où JobID IN (a, b, c):

  var Results = 
      from item in Job.All() 
      where (_IDs as IEnumerable<Guid>).Contains(item.JobID) 
      select item; 

Je veux être en mesure d'appeler cette méthode sur les tables autres que Job, avec des touches autres que JobID. Le GetAll Func fonctionne car il renvoie le même IQueryable que Job.All(), mais GetID lève une exception d'exécution, "noeud d'expression LINQ de type Invoke n'est pas supporté". GetID renvoie une valeur, mais ce dont j'ai vraiment besoin est quelque chose que Contient (item.JobID) reconnaîtrait comme un nom de colonne et que la syntaxe "where" accepterait. (Je ne le montre pas ici, mais j'ai le même problème avec orderby.)

Est-ce possible, avec ce que vous savez de SubSonic3?

+0

J'ai lu ce une ou deux fois, et je dois dire que je ne suis pas Assurez-vous du résultat final que vous essayez d'atteindre. Vous montrez deux extraits de code qui semblent atteindre le même résultat - l'un utilisant uniquement LINQ et la classe ActiveRecord et l'autre utilisant votre méthode générique. Peut-être pourriez-vous ajouter un extrait de code avec lequel vous essayez de vous retrouver et qui ne fonctionne pas? Je pense que vous essayez d'utiliser votre méthode générique dans une requête LINQ plus grande, mais encore une fois, je suis vraiment incertain. –

+0

Merci d'avoir jeté un coup d'oeil. Ce que j'essaye d'accomplir est d'obtenir le paramètre des Contient être "item.JobID" quand T est Job, mais "item.WhateverID" quand T est Whatever. J'ai un certain nombre de tables avec une logique de recherche qui est unique à chacun; la logique de recherche construit la Liste des Guides. Une fois que j'ai cela, chaque table a alors cette même logique pour sélectionner les objets en utilisant WHERE "key" IN (Guid1, Guid2, ...). Même chose, dis-je, sauf pour la table et la colonne clé. GetAll résout le problème de la table, mais GetID ne résout pas le problème de la colonne. Est-ce plus clair? –

+0

Je peux avoir une vision tunnel: mon résultat final REAL désiré est la requête SQL SELECT * FROM Job où JobID IN (a, b, c), où ma méthode générique peut fonctionner pour (1) n'importe quelle table (en dehors de Job), (2) n'importe quelle touche (en dehors de JobID), et (3) n'importe quelle liste de valeurs de clé. J'ai (1) et (3), mais pas (2). –

Répondre

0

Ma solution était de passer dans l'expression qui en cas de besoin:

public List<T> GetFromList(List<Guid> _IDs, 
    Func<IQueryable<T>> GetAll, 
    Expression<Func<T, bool>> _where) 
     where T : class, U, IActiveRecord 
{ 
    List<T> rc = new List<T>(); 
    if (0 < _IDs.Count) 
    { 
     if (MAX_ITEMS > _IDs.Count) 
     { 
      var Results = GetAll().Where(_where); 
      rc = Results.ToList(); 
     } 
     else 
     { 
      var Results = 
       from id in _IDs 
       join item in GetAll() on id equals item.KeyValue() 
       select item; 
      rc = Results.ToList(); 
     } 
    } 
    return rc; 
} 

appelé par

rc = GetFromList(
     IDList, 
     () => Job.All(), 
     (item => (IDList as IEnumerable<Guid>).Contains(item.JobID))); 
Questions connexes