2010-11-26 28 views
5

j'ai une méthode d'extension dont une personne était vraiment utile de me donner ... il fait un orderby sur IQueryable ... mais je voulais faire un un IQueryable normal (non générique)IQueryable (non générique): Comte et Ignorer manquant? il fonctionne avec IQueryable <T>

Voici le code, Le compte et Skip et je pense que Take sont manquants.

public static IQueryable GetPage(this IQueryable query, 
     int page, int pageSize, out int count) 
    { 
     int skip = (int)((page - 1) * pageSize); 

     count = query.Count(); //COUNT DOESN'T EXIST 
     return query.Skip(skip).Take((int)pageSize); // NEITHER SKIP 
    } 

Voici la et cela fonctionne parfaitement sans erreurs.

public static IQueryable<T> GetPage<T>(this IQueryable<T> query, 
     int page, int pageSize, out int count) 
    { 
     int skip = (int)((page - 1) * pageSize); 

     count = query.Count(); 
     return query.Skip(skip).Take((int)pageSize); 
    } 

Des idées comment je peux contourner ce problème? Je ne veux pas changer mes types de retour comme il fonctionne parfaitement et j'ai une autre méthode d'extension appelée ToDataTable et il fonctionne également sur un IQueryable non générique.

Y at-il un travail autour?

Merci à l'avance

EDIT

Je l'appelle comme si sur une IQueryable existante

IQueryable<Client> gen = null; 
IQueryable nongen = null; 

var test = gen.GetPage(); //COMPILES! 

var test 1 = non.GetPage(); // Doesn't compile because GETPAGE 
          // for non generic is broken as it has 
          // invalid methods like COUNT and SKIP etc. 

J'ai essayé de supprimer la version GetPage non générique mais mon non générique IQueryable n » t ramasser l'extension en raison du fait que ce n'est pas un Iqueryable mais seulement un IQueryable

Répondre

11

Nous ll, tout simplement ces méthodes ne sont pas disponibles pour IQueryable. Si vous regardez le Queryable methods, vous verrez qu'ils sont presque tous basés sur IQueryable<T>.

Si votre source de données vraiment être un IQueryable<T> au moment de l'exécution, et vous ne savez pas ce que T est, alors vous pouvez constater que avec la réflexion ... ou en C# 4, il suffit d'utiliser dynamique frappe:

public static IQueryable GetPage(this IQueryable query, 
    int page, int pageSize, out int count) 
{ 
    int skip = (int)((page - 1) * pageSize); 
    dynamic dynamicQuery = query; 
    count = Queryable.Count(dynamicQuery); 
    return Queryable.Take(Queryable.Skip(dynamicQuery, skip), pageSize); 
} 

le bit dynamique du compilateur C# prendra soin de travailler pour vous T au moment de l'exécution.

En général, cependant, je vous encourage à essayer simplement d'utiliser le formulaire générique partout à la place - il est susceptible d'être beaucoup plus simple.

+0

Merci JOn! Vous dites C# 4.0 - j'utilise 3.5 .. Donc je peux utiliser une réflexion standard dans 3.5 ?? je suppose? – Martin

+1

@Martin: Oui. Vous devriez obtenir le type concret de 'query' et découvrir quelles interfaces il implémente ... découvrez' T' via cela, puis utilisez 'MethodInfo.MakeGenericMethod' pour appeler' Queryable.Count' etc. Il est probable se salir très rapidement. –

+0

Oui !! Oh bien va penser ... :-) Merci pour la confirmation. – Martin

0

La question est ancienne, mais quand quelqu'un a besoin des méthodes d'extension IQueryable, il/elle devrait retourner IQueriable lorsque le type de retour est anonyme.