2010-11-30 2 views
2

Je rencontre un problème lors de la modification des propriétés d'objets dans une collection IEnumerable. Je passe la collection à une autre méthode pour supprimer les informations en double dans les entités de la collection. Cela fonctionne dans la méthode mais une fois la méthode exécutée et renvoyée à l'appelant, les modifications sont perdues. Toutefois, si je convertis IEnumerable en une liste, cela fonctionne comme prévu. Ma seule supposition est que parce que quand j'appelle ToList ça devient un type concret et ça lui permet de fonctionner, mais ça ne devrait pas être une limitation, n'est-ce pas?Impossible de modifier les propriétés des objets dans un IEnumerable <T>

Aussi, cela ne vaut rien que ce n'est pas dans le cadre d'une exécution différée. Cela a fini par ne pas être vrai, le compilateur a été réécrit la méthode RetrieveTrackingFilters pour tirer profit de exécution différée

Ceci est le code dégrossi:

public IEnumerable<TrackingFilter> RetrieveTrackingFilters(string proNumber) 
{ 
    var trackingFilters = new EntityCollection<TrackingOverviewFilterEntity>(new TrackingOverviewFilterEntityFactory()); 

    var filter = new RelationPredicateBucket(); 
    filter.Relations.Add(TrackingOverviewFilterEntity.Relations.TrackingOverviewEntityUsingTrackingOverviewId); 
    filter.PredicateExpression.Add(TrackingOverviewFields.ProNumber == proNumber); 

    DataAccessAdapterFactory.Instance().FetchEntityCollection(trackingFilters, filter); 

    return BuildTrackingFilterColl(trackingFilters); //Just news up a DTO object and populates it 
} 

public TrackingSummaryViewModel RetrieveTrackingSummary(string proNumber) 
{ 
    ... 
    var trackingFilters = this._TrackingOverviewDataController.RetrieveTrackingFilters(proNumber).ToList(); //Works 
    //var trackingFilters = this._TrackingOverviewDataController.RetrieveTrackingFilters(proNumber); //Doesn't work 

    RemoveDuplicateFilterData(trackingFilters); //If I don't do a ToList() then the changes that occur in this method call do not persist 
    ... 
} 

private static void RemoveDuplicateFilterData(IEnumerable<TrackingFilter> filters) 
{ 
    var valuePairs = new Dictionary<string, IList<object>>(); 

    foreach (var filter in filters) 
    { 
     if (valuePairs.ContainsKey("comments") && valuePairs["comments"].Contains(filter.Comments)) 
     { 
      filter.Comments = string.Empty; 
     } 
     else if (!string.IsNullOrWhiteSpace(filter.Comments)) 
     { 
      if (!valuePairs.ContainsKey("comments")) 
      { 
       valuePairs.Add("comments", new List<object>()); 
      } 

      valuePairs["comments"].Add(filter.Comments); 
     }  
    } 

    ... 
} 
+2

'.ToList()' n'est pas un cast à une liste, c'est une méthode d'extension qui crée une nouvelle liste avec les valeurs d'un IEnumerable. Le résultat n'est pas l'ancienne structure castée vers une liste, mais une nouvelle structure avec les mêmes éléments que l'ancienne. –

+0

@albin sunnanbo, désolé, vous avez raison, j'ai utilisé le mauvais verbiage. Je le savais réellement. – joshlrogers

+0

Votre type est-il réellement struct? –

Répondre

3

Si votre RetrieveTrackingFilters(proNumber) retourne un IQueryable, cette entraînerait la création de nouveaux objets chaque fois que vous l'énuméreriez: une fois dans RemoveDuplicateFilterData (les modifications seraient alors perdues) et une fois lorsque vous en feriez quelque chose plus tard dans RetrieveTrackingSummary (une nouvelle copie, intacte, serait fournie à ce stade).

Essayez de remplacer .ToList() par .AsEnumerable(). Il devrait toujours fonctionner de la même manière.

+0

La première méthode dans mon code est le RetrieveTrackingFilters et il renvoie un IEnumerable . – joshlrogers

+0

@joshlrogers, IQueryable implémente IEnumerable , ainsi un IQueryable peut être "caché" dans un IEnumerable. –

+0

@joshlrogers, vérifiez le type d'exécution dans le débogueur –

Questions connexes