2010-11-09 7 views
2

Quelqu'un peut-il m'aider à évaluer pourquoi le code ci-dessous ne fonctionne pas. J'utilise la méthode d'extension commune pour implémenter Include lors de l'utilisation de IObjectset. Dans nos dépôts, nous ne voyions pas cela correctement, donc j'ai isolé le code dans l'application de test comme ci-dessous. J'ai également inclus le contexte basé sur l'interface si cela peut s'avérer pertinent et une capture d'écran de la section de modèle pertinente. Cela se produit pour tous Inclut sur les propriétés IObjectSet pas seulement le DPASelections que j'ai choisi pour cet exemple.Problème avec l'extension Include sur IObjectSet ne fonctionnant pas

Si je mets à jour le contexte pour retourner ObjectSet (toujours en utilisant les entités POCO) plutôt que IObjectSet, tout fonctionne correctement. Lorsque j'utilise IObjectSet et la méthode d'extension et que je parcours le code, je vois que la méthode d'extension se termine correctement avec un appel à ObjectQuery que nous sommes en train de lancer, mais les entités incluses ne sont jamais renvoyées sur le graphique. Comme je l'ai dit, cela fonctionne parfaitement lorsque je n'interface pas le contexte et que je retourne des propriétés ObjectSet, ce qui m'appelle directement Include sur ObjectSet.

Je ne reçois aucune erreur lors de l'exécution de la requête, donc ce n'est pas la même chose que plusieurs autres questions sur SO qui se réfèrent aux requêtes compilées.

Est-ce que quelqu'un d'autre a rencontré des problèmes avec cette implémentation de méthode d'extension ou quelqu'un peut-il repérer ce que je fais mal ici?

Toute aide très appréciée.

 static void Main(string[] args) 
    { 
     using (var context = new AssocEntities()) 
     { 
      context.ContextOptions.LazyLoadingEnabled = false; 
      Candidate candidate = context.Candidates 
             .Include("DPASelections.DPAOption") 
             .SingleOrDefault(c => c.Number == "N100064"); 

      //Count is 0 when using ext. method and IObjectSet through AssocContext but correct when using Include 
      //on ObjectSet through AssocContext 
      Console.WriteLine("DPASelection count = {0}",candidate.DPASelections.Count); 

      //This is always null when using IObjectSet and ext. method but populated 
      //when using Include on ObjectSet 
      var option = candidate.DPASelections.First().DPAOption; 

      Console.WriteLine("First DPAOption = {0} : {1}",option.Id,option.Text); 

     } 

     Console.ReadLine(); 
    } 
} 

public static class Extensions 
{ 
    public static IQueryable<TSource> Include<TSource>(this IQueryable<TSource> source, string path) 
    { 
     var objectQuery = source as ObjectQuery<TSource>; 

     if (objectQuery != null) 
     { 
      objectQuery.Include(path); 
     } 

     return source; 
    } 
} 

//Subset of custom context implementing IObjectSet as returns. 
//Works fine when I return ObjectSet rather than IObjectSet and use 
//the Include method directly 
public partial class AssocEntities : ObjectContext 
{ 
    public const string ConnectionString = "name=AssocEntities"; 
    public const string ContainerName = "AssocEntities"; 

    #region Constructors 

    public AssocEntities() 
     : base(ConnectionString, ContainerName) 
    { 
     this.ContextOptions.LazyLoadingEnabled = true; 
    } 

    public AssocEntities(string connectionString) 
     : base(connectionString, ContainerName) 
    { 
     this.ContextOptions.LazyLoadingEnabled = true; 
    } 

    public AssocEntities(EntityConnection connection) 
     : base(connection, ContainerName) 
    { 
     this.ContextOptions.LazyLoadingEnabled = true; 
    } 

    #endregion 

    #region IObjectSet Properties 

    public IObjectSet<Address> Addresses 
    { 
     get { return _addresses ?? (_addresses = CreateObjectSet<Address>("Addresses")); } 
    } 
    private IObjectSet<Address> _addresses; 

    public IObjectSet<Answer> Answers 
    { 
     get { return _answers ?? (_answers = CreateObjectSet<Answer>("Answers")); } 
    } 
    private IObjectSet<Answer> _answers; 

    public IObjectSet<Candidate> Candidates 
    { 
     get { return _candidates ?? (_candidates = CreateObjectSet<Candidate>("Candidates")); } 
    } 
} 

Et le modèle ... alt text

+0

je l'ai utilisé la même configuration exacte, et il fonctionne très bien pour moi (ne marche pas vraiment vous aider, mais je pensais id mentionner que). avez-vous traversé le code - est-ce que votre méthode d'extension est appelée, avez-vous exécuté la trace du profileur, etc. – RPM1984

+0

Ext. Le code de la méthode s'exécute correctement et appelle dans la base de données, mais la requête produite ignore simplement l'inclusion et renvoie uniquement le candidat. –

+0

@Daz Lewis - avez-vous essayé '.Include (" DPASelections "). Include (" DPASelections.DPAOption ")' Je ne pense pas que vous pouvez aller directement à un nav double imbriqué. (Je peux me tromper). reste simple, fait 'context.Candidates.Include (" Grade "). FirstOrDefault()' fonctionne? – RPM1984

Répondre

1

je devais remplacer objectQuery.Include(path); avec objectQuery = objectQuery.Include(path);

0

Dans .Net 4.0 cadre il y a une accumulation dans Extentionmethod pour Include juste ajouter l'espace de noms System.Data.Entity .

Il utilise la réflexion - voici comment cela fonctionne:

private static T CommonInclude<T>(T source, string path) 
{ 
    MethodInfo method = source.GetType().GetMethod("Include", DbExtensions.StringIncludeTypes); 
    if (!(method != (MethodInfo) null) || !typeof (T).IsAssignableFrom(method.ReturnType)) 
    return source; 
    return (T) method.Invoke((object) source, new object[1] 
    { 
    (object) path 
    }); 
} 
Questions connexes