0

I'm building an app to display the historical log of changes from a source control repository. The app is implemented in .NET 4 WPF and Entity Framework Code First.

One of the problems I'm getting is that over time, as more log entries are added to the log, the application uses more and more memory and doesn't release references to the log entries. Each log entry holds a list of "changed files" and for each changed file, the before and after version of the file.

The UI displays a list of log entries and the diff between the old and new version of the currently selected LogEntry and ChangedFile. The data model is roughly as follows:

public class LogSubscription
{
    public List<LogEntry> Log { get; set; }
}

public class LogEntry
{
    public List<ChangedFile> ChangedFiles { get; set; }
}

public class ChangedFile
{
    public string OldVersion { get; set; }
    public string NewVersion { get; set; }
}

As I'm using EF Code First, the database is queried and the object model is built automatically by simply accessing the List properties. What I'd like to do is somehow de-reference the ChangedFiles list after a certain time and have the database re-queried and the object model rebuilt as necessary (i.e. the user has clicked back onto the log entry).

Is there any way to do this with EF Code First? Or should I be taking a different approach to control the memory used?

The app and full source code is hosted on GitHub here: https://github.com/tomhunter-gh/SourceLog

Tom Hunter
  • 5,714
  • 10
  • 51
  • 76
  • 1
    If you are using single context instance for the application it will hold all references to loaded entities until you manually detach them or release the context instance. – Ladislav Mrnka Oct 29 '12 at 09:07
  • Thanks @LadislavMrnka. Is it basically the case that you can't use lazy loading when you dispose of the context? I think this is where I'm getting confused and where I had issues before.. – Tom Hunter Oct 29 '12 at 20:03

1 Answers1

1

As said in the comment: this is likely to happen with a static context that is never disposed. I see in the source that there is a ThreadStaticContextBackground which is used by a LogEntry: in an active-record like pattern a LogEntry saves itself by its MarkAsReadAndSave method, for which it needs a context.

You probably did this (I did not really scrutinize the source) to prevent creating and disposing many contexts while saving logs entries. But I think you should rethink the active record approach. Log entries are saved by the MainWindowViewModel. The view model should invoke a service method that saves log entries by a short-lived context and possibly caches the entries to have them available for display etc. And it should receive the RemovedItems collection from DgLogSelectionChanged in order to have them handled by one context instead of one context per item. Does that make any sense?

Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
  • Thanks for the feedback @Gert. I guess the question is can I do lazy loading without a static context reference? If I don't hold a static reference, how would I do the lazy loading and un-loading of the ChangeFiles collection? Any links to articles would be appreciated - I'm not finding much on the unloading question.. Thanks – Tom Hunter Oct 30 '12 at 11:28
  • No, you can't do lazy loading without a context, but maybe you should have service method that supplies data when needed in stead of relying on an object's navigation property. Thus, unloading would be easier: just empty or dispose a collection variable. – Gert Arnold Oct 30 '12 at 11:32
  • Yep, this makes sense. Quick question - if I empty the collection property and then save the parent entity would this delete the entities in the collection? Are there any examples of this behaviour you could point me at? Thanks – Tom Hunter Oct 30 '12 at 11:37
  • If you load a collection and then clear it, yes EF will see this as a request to remove the entities or at least break the association with the parent object. See e.g. [this question](http://stackoverflow.com/questions/4708033/entity-framework-delete-child-objects). – Gert Arnold Oct 30 '12 at 12:24