Unable to modify the properties of objects within an IEnumerable<T>

I am having a problem making changes to the properties of objects in an IEnumerable collection. I pass the collection to another method to remove duplicate information across the entities within the collection. This works within the method but once the method is done executing and returns to the caller the changes are lost. However, if I convert the IEnumerable to a list it works as expected. My only guess is that because when I call ToList it becomes a concrete type and that allows it to work, but that shouldn't be a limitation, right?

Also it is worth nothing that this isn't in the context of deferred execution. This ended up not being true, the compiler was rewriting the RetrieveTrackingFilters method to take advantage of deferred execution

This is the trimmed down code:

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);
        }    
    }

    ...
}

Answers


If your RetrieveTrackingFilters(proNumber) returns an IQueryable, then this would cause new objects to be created each time you enumerate it: once within RemoveDuplicateFilterData (the changes there would then be lost) and once when you do something with it later in RetrieveTrackingSummary (a fresh, untouched copy would be provided at this point).

Try changing .ToList() to .AsEnumerable(). It should still work the same.


Need Your Help

Database schema for a hierarchial groups

sql-server database database-design

I'm working on a database design for groups hierarchy used as the foundation of a larger system. Each group can contain other groups, and also 'devices' as leaf objects (nothing goes below device)....