开发者

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<o开发者_StackOverflow中文版bject>());
            }

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

    ...
}


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜