2017-07-23 2 views
0

La méthode d'extension IQueryable est correcte dans la méthode normale, mais pas dans une méthode générique.Erreur de compilation de la méthode d'extension IQueryable à partir de la méthode générique

Erreur de compilation: IQueryable ne contient pas de définition de la meilleure et Mon extension l'extension méthode surcharge DataExtensions.MyExtension (IQueryable Fred) nécessite un récepteur de type IQueryable Fred

L'objectif est tourner la // do something interesting ci-dessous en méthode générique qui fonctionnerait tous les types FlintstoneObject.

public static class RepetitiveCodeBelow 
{ 
    public static int RepetitiveCode() 
    { 
     var count = 0; 
     using (var context = new DataContext()) 
     { 
      foreach (var data in context.Freds.AsNoTracking().Where(item => item.PrimaryKey > 0).MyExtension()) 
      { 
       // do something interesting 
      } 

      foreach (var data in context.Barnies.AsNoTracking().Where(item => item.PrimaryKey > 0).MyExtension()) 
      { 
       // do something interesting 
      } 

      // more types omitted 
     } 
     return count; 
    } 
} 

version de travail:

public List<Fred> GetFredList() 
    { 
     using (var context = new DataContext()) 
     { 
      return context.Freds.AsNoTracking().MyExtension().ToList(); 
     } 
    } 

Wont compilation:

public List<T> GetList<T>() where T : FlintstoneObject<T>, new() 
    { 
     using (var context = new DataContext()) 
     { 
      return context.Set<T>().AsNoTracking().MyExtension().ToList(); 
     } 
    } 

Échantillon complet

public abstract class FlintstoneObject<T> where T : class 
{ 
    public abstract int PrimaryKey { get; set; } 
} 

public class Fred : FlintstoneObject<Fred> 
{ 
    public override int PrimaryKey { get; set; } 
} 

public class Barny : FlintstoneObject<Barny> 
{ 
    public override int PrimaryKey { get; set; } 
} 

public static class DataExtensions 
{ 
    public static IQueryable<Fred> MyExtension(this IQueryable<Fred> queryable) 
    { 
     return queryable; 
    } 
} 

public class DataContext : DbContext 
{ 
    public DbSet<Fred> Freds { get; set; } 
    public DbSet<Barny> Barnies { get; set; } 

    public List<Fred> GetFredList() 
    { 
     using (var context = new DataContext()) 
     { 
      return context.Freds.AsNoTracking().MyExtension().ToList(); 
     } 
    } 

    public List<T> GetList<T>() where T : FlintstoneObject<T>, new() 
    { 
     using (var context = new DataContext()) 
     { 
      return context.Set<T>().AsNoTracking().MyExtension().ToList(); 
     } 
    } 
} 
+0

Le message d'exception est explicite. Basé sur votre version actuelle de la méthode d'extension, il ne fonctionnera que sur «IQueriable ». Qu'essayez-vous finalement de faire? – Nkosi

+0

L'erreur me semble raisonnablement claire. Votre méthode d'extension est valide uniquement pour une expression ayant le type 'IQueryable '. Mais dans votre méthode générique, la seule chose que le compilateur peut prouver est que le type est 'IQueryable ' où 'T: FlintstoneObject '. Ce n'est pas assez bon d'appeler une méthode qui nécessite 'IQueryable '. Il existe des alternatives possibles qui compileraient. Malheureusement, votre question ne fournit pas suffisamment de contexte pour savoir quelles options, le cas échéant, pourraient fonctionner dans votre cas. –

+0

Mon objectif est de consolider en 1 méthode, un nombre d'extraits qui sont presque identiques, la différence étant le type manipulé: Fred, Barny, etc. –

Répondre

0

Votre code est Probab manquant de cette extension:

public static IQueryable<T> MyExtension<T>(this IQueryable<T> queryable) 
    { 
     return queryable; 
    } 

pour le rendre compilable.

Quoi qu'il en soit, ce que vous aviez l'intention de faire avec votre truc générique semble étrange:

public class Fred : FlintstoneObject<Fred> 

Je pensais que T devrait être une classe autre que Fred qui hérite du type générique FlintstoneObject<T>.

+0

Ce n'est pas ce que je veux. Avoir cette méthode signifie que je dois vérifier T par rapport aux types connus et appeler la fonction spécialisée appropriée. –