2010-11-23 22 views
0

J'utilise le dernier Nhibernate et j'ai une requête linq pour retourner seulement 1 colonne. donc je ne peux pas utiliser par exemple IQueryable car il n'y a pas de classe d'entité - je ne retourne qu'une seule colonne. Mais revenir à IQueryable version non générique ne fournit pas la méthode ToListNhibernate 3.0 LINQ: Problème renvoyé à IQueryable (version non générique) - n'autorise pas ToList()

Voici la méthode

public IQueryable GetCode() 
    { 
     using (ITransaction transaction = _session.BeginTransaction()) 
     { 

      var results = (from c in _session.Query<Client>() 
          select new 
          { 
           Group = c.Code 
          }).Distinct(); 

     } 
    } 

Bien sûr, si je le fais (voir ci-dessous) je reçois la méthode ToList sur mon IQueryable

public IQueryable<Client> GetCode() 
    { 
     using (ITransaction transaction = _session.BeginTransaction()) 
     { 

      var results = (from c in _session.Query<Client>() 
          select c; 

     } 
    } 

Le problème étant que je dois faire DISTINCT et utiliser seulement 1 colonne.

Toutes les idées, je suis à une perte

Merci à l'avance

EDIT

Quand je regarde le type qui est retourné par IQueryable il est

{NHibernate. Linq.NhQueryable < <> f__AnonymeType6>}

et en regardant sous la classe de base de ce qui est retourné je vois une exception

Le type d'expression 10005 n'est pas supporté par ce SelectClauseVisitor.

+0

Pourquoi vous enveloppez une transaction (qui est juste disposé) autour de la requête? Cela semble problématique pour plusieurs raisons. – Paco

+0

Oui Paco, tu as raison mais ça ne résout pas le problème – Martin

Répondre

1

Les solutions suivantes ne fonctionneraient-elles pas?

public IQueryable<X> GetCode() // X = the type of Client.Code 
{ 
    using (ITransaction transaction = _session.BeginTransaction()) 
    { 

     var results = (from c in _session.Query<Client>() 
         select c.Code).Distinct(); 

    } 
} 

Le problème ici est non seulement que vous ne pouvez pas appeler ToList sur un IQueryable non générique, mais que tout le résultat est typées, de sorte que vous ne pouvez pas lire la propriété Code de chaque élément soit. (Cela peut être travaillé avec le type dynamique de C# 4, mais ce n'est pas vraiment ce que vous voulez ici.)

Dans votre cas, je ne vois pas pourquoi vous avez vraiment besoin de construire un type anonyme juste pour retourner une séquence distincte de Code valeurs renommées en tant que Group. Le retour de la valeur du champ devrait être suffisant.

Si vous avez besoin de revenir plus qu'une seule colonne, vous devez créer un type explicite, plutôt que d'utiliser un type anonyme, de sorte que vous pouvez dire

public IQueryable<ClientGroupAndSomething> GetCode() 
{ 
    using (ITransaction transaction = _session.BeginTransaction()) 
    { 

     var results = (from c in _session.Query<Client>() 
         select new ClientGroupAndSomething 
         { 
          Group = c.Code, 
          ... 
         }).Distinct(); 

    } 
} 
+0

Merci Ruben! N'y a-t-il pas d'autre moyen si je veux retourner plus d'une colonne? Dois-je créer un type explicite? – Martin

+0

Il existe toujours des solutions de contournement, telles que l'utilisation du type de retour 'IQueryable ' (C# 4) plutôt qu'un simple 'IQueryable'. Bien que je ne sais pas si NHibernate le supporte. Et puis vous ne travaillez plus avec (compilateur vérifié) le code typé statiquement. Un 'IQueryable 'non générique efface les informations de type statique, de sorte que vous avez une requête renvoyant des éléments d'un type inconnu. Pour cette raison, les types anonymes ('new {...}') ne devraient jamais échapper une méthode. – Ruben

+0

Merci! Excellent ... très apprécié – Martin