How can I keep / keep synchronization in memory of graphs of objects with the database?

Question. What is the best best practice approach for how I can keep / keep the objects jn-memory graph in sync with the database?

Background:

That is, I have Node and Relationship classes and the application creates a graph of related objects using those classes. There can be 1000 nodes with different relationships between them. The application needs to query the structure, so the in-memory approach is good for performance without a doubt (e.g. traverse the graph from Node X to find the root parents)

However, the graph must be saved in a database with the NODES and RELATIONSHIPS tables.

So what is a good best practice approach, how can I keep / keep the objects jn memory graph in sync with the database?

Ideal requirements include:

  • create changes in memory and then save them (required)
  • when saving, apply database updates in the correct order to avoid hitting any database constraints (required)
  • save a save mechanism different from the model, for the convenience of changing the save layer if necessary, for example. don't just port ADO.net DataRow to Node classes and relationships (preferable)
  • mechanism for optimistic locking (desirable)

Or is it the overhead of it all for a small application that just isn't worth it and I have to just hit the database every time for everything? (assuming response times were acceptable) [would still like to avoid, if not too much additional overhead, to remain somewhat scalable in terms of performance]

+2


a source to share


2 answers


I am using self-monitoring objects in Entity Framework 4. After the objects are loaded into memory, StartTracking () MUST be called on each object. Then you can change the object graph in memory without any DB-Operations. When you're done making your changes, you call the "ApplyChanges (rootOfEntityGraph)" context extension method and SaveChanges (). Therefore, your modifications are saved. Now you need to start tracking again for each object in the graph. Two hints / ideas I'm using at the moment:

1.) call StartTracking () at the beginning on each entity

I am using IWorkspace interface to abstract ObjectContext (makes testing easier -> see OpenSource bbv.DomainDrivenDesign implementation in sourceforge). They also use QueryableContext. So I created another concrete implementation of Workspace and QueryableContext and intercepted the loading process with my own IEnumerable implementation. When a workspace user makes a request that he receives using CreateQuery (), my IEnumerable object interceptor registers an event handler in the ChangeTracker context. In this case, the handler I call StartTracking () for every object loaded and added to the context (does not work if you load objects using NoTrakcing, because in this case the objects are not added to the context and the event handler will not be fired).Once enumerated in a homemade Iterator, the event handler on the ObjectStateManager is canceled.

2.) call StartTracking () after ApplyChanges () / SaveChanges ()

In the workspace implementation, I set the ObjectStateManager context for the modified objects, i.e.

var addedEntities = this.context.ObjectStateManager.GetObjectStateEntries (EntityState.Added); -> similarly for modified objects



pass them to IObjectWithChangeTracker and call AcceptChanges () method on the entity itself. This will launch the changetracker object again.

For my project, I have the same required scores as yours. I've been playing around with EF 3.5 and haven't found a satisfying solution. But the new ability of self check objects in EF 4 seems to fit my requirements (as far as I studied functionality).

If you are interested, I will send you my "spike" project.

Is there an alternative solution? My project is a server-side application that keeps objects in memory for fast operations, while modifications must be saved as well (no rounding to DB). At some points in the code, graphic objects are marked as deleted / completed and removed from the container in memory. With the solution above explained, I can reuse the generated model from EF and not rewrite and wrap all objects again. The generated code for self-test objects comes from T4 templates that can be easily adapted.

Thanks a lot for other ideas / criticism

+1


a source


The short answer is that you can still store a graph (set of related objects) of objects in memory and write changes to the database as they occur. If it takes too long, you can push the changes to the message queue (but this is probably too much), or perform updates and inserts on a separate thread.



0


a source







All Articles