2016-10-11 1 views
0

J'ai ajouté la méthode d'extension suivanteDbSet inclure la méthode boucle

/// <summary> 
    /// Provides a statically typed interface for db includes 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="set">The set.</param> 
    /// <param name="includes">The includes.</param> 
    /// <returns>DbSet&lt;T&gt;.</returns> 
    public static DbSet<T> Include<T>(this DbSet<T> set, params Expression<Func<T, object>>[] includes) where T : class 
    { 
     if (includes != null) 
     { 
      foreach (var expression in includes) 
      { 
       set.Include(expression); 
      } 
     } 
     return set; 
    } 

Ceci est basé sur le code référentiel je trouve ici

https://github.com/carbonrobot/FullStackEF/tree/master/src

extension Cependant, quand j'utiliser cela avec la suivant

public ServiceResponse<Town> Get(int id) 
    { 
     Func<Patient> func = delegate 
     { 
      using (var context = _contextFactory()) 
      { 
       return context.Get<Town>(id, x => x.County); 
      } 
     }; 
     return this.Execute(func); 
    } 

Lorsque la classe de la ville contient un comté en tité.

Je reçois une boucle infinie en appelant la méthode d'extension plutôt que la base incluse?

Des idées de ce que je fais mal ici?

Répondre

1

Il y a plusieurs erreurs dans cette méthode.

La méthode DbExtensions.Include a la signature suivante:

public static IQueryable<T> Include<T, TProperty>(
    this IQueryable<T> source, 
    Expression<Func<T, TProperty>> path 
) 
where T : class 

Comme vous pouvez le voir, il reçoit IQueryable<T> et retourne une autre IQueryable<T> qui doit être affecté à une variable et retournée au lieu de l'original pour a un effet , que le code ne fait pas.

En outre, étant donné que la méthode appelle Include sur la variable set de type DbSet<T> qui est plus concret que le IQueryable<T>, et l'argument correspond à la signature de la méthode personnalisée, le compilateur appelle simplement la même méthode, d'où le StackOverflowException.

Cela étant dit, voici la signature de méthode correcte personnalisée et la mise en œuvre:

public static IQueryable<T> Include<T>(this DbSet<T> set, params Expression<Func<T, object>>[] includes) 
    where T : class 
{ 
    var result = set.AsQueryable(); 
    if (includes != null) 
    { 
     foreach (var expression in includes) 
     { 
      result = result.Include(expression); 
     } 
    } 
    return result; 
} 
+0

merci pour l'explication détaillée. Une question cependant que le repo utilise le DbSet retourné pour enchaîner les méthodes. ie.include (includes) .find (id) Comme la méthode d'extension est return IQueryable (par opposition à DbSet Je perds la capacité d'enchaîner? des idées avec ceci? –

+0

Hmm, cela semble insoluble, mais 'Include' doesn ' t fonctionne avec 'Find' de toute façon, donc je suppose que cela n'a aucun sens d'être enchaîné avec' Find' Les chaînes régulières de LINQ devraient fonctionner, mais la raison en est que le résultat de 'Include' n'est plus' DbSet' –

+0

Ok Donc, fondamentalement, vous recommandez simplement .include (includes) .select (x => x.Id == id); (par rapport à l'exemple de recherche) .Pour filtrer les résultats interrogeables? –