Question - Exactly what is a good best practice method for how do i save/keep-in-sync an jn-memory graph of objects using the database?
That's say I've the classes Node and Relationship, and also the application is accumulating a graph of related objects with such classes. There can be 1000 nodes with assorted associations together. The applying must query the dwelling hence an in-memory approach will work for performance without doubt (e.g. traverse the graph from Node X to obtain the root parents)
The graph needs to be endured however right into a database with tables NODES and Associations.
Therefore exactly what is a good best practice method for how do i save/keep-in-sync an jn-memory graph of objects using the database?
Ideal needs would come with:
- develop alterations in-memory after which 'save' later on (mandatory)
- when saving, apply updates to database in correct to avoid striking any database constraints (mandatory)
- keep persistence mechanism outside of model, for ease in altering persistence layer as needed, e.g. don't just wrap an ADO.internet DataRow within the Node and Relationship classes (desirable)
- mechanism for doing positive securing (desirable)
Or perhaps is the overhead of this for any smallish application simply not worthwhile and that i must hit the database every time for everything? (presuming the response occasions were acceptable) [would still prefer to avoid if little extra overhead to stay somewhat scalable re performance]
I am while using self monitoring organizations in Entity Framework 4. Following the organizations are loaded into memory the StartTracking() Should be known as on every entity. You'll be able to modify your entity graph in memory with no DB-Procedures. When you are completed with the modifications, you call the context extension method "ApplyChanges(rootOfEntityGraph)" and SaveChanges(). So that your modifications are endured. Now you must to begin the monitoring again on every entity within the graph. Two hints/ideas I am using right now:
1.) call StartTracking() at the start on every entity
I am utilizing an Interface IWorkspace to abstract the ObjectContext (simplifies testing -> begin to see the OpenSource implementation bbv.DomainDrivenDesign at sourceforge). Additionally they make use of a QueryableContext. And So I produced an additional concrete Workspace and QueryableContext implementation and intercept the loading process by having an own IEnumerable implementation. Once the workspace's consumer executes the query that they get with CreateQuery(), my intercepting IEnumerable object registers an eventhandler around the context's ChangeTracker. Within this event handler I call StartTracking() for each entity loaded and added in to the context (does not work should you load the objects with NoTrakcing, because for the reason that situation the objects aren't put into the context and also the event handler won't be fired). Following the enumeration within the self made Iterator, the big event handler around the ObjectStateManager is deregistered.
2.) call StartTracking() after ApplyChanges()/SaveChanges()
Within the workspace implementation, I request the context's ObjectStateManager for that modified organizations, i.e:
var addedEntities = this.context.ObjectStateManager.GetObjectStateEntries(EntityState.Added) --> similar for modified organizations
cast these to IObjectWithChangeTracker and call the AcceptChanges() method around the entity itself. This begins the object's changetracker again.
For my project I have a similar mandatory points while you. I performed around with EF 3.5 and did not look for a acceptable solution. However the new ability of self monitoring organizations in EF 4 appears to suit my needs (so far as I investigated the funcionality).
If you are interested, I'll give back my "spike"-project.
Have anybody a different? My project is really a server application which holds objects in memory for fast procedures, while modifications ought to be endured (no round visit to DB). At some things in code the item graphs are marked as erased/ended and therefore are taken off the in-memory container. Using the described solution above I'm able to reuse the produced model from EF and haven't to code and wrapp all objects myself again. The produced code for that self monitoring organizations comes from T4 templates which may be modified effortlessly.
Thanks for other ideas/critism