Object Infrastructure Share ObjectContext - Pros and Cons

In my project, I use the framework 4.0 entity as ORM to save data to SQL Server.

My project is a ribbon from an application with a grid and a navigation tree in the main form with a ribbon panel on top of it. My application mainly works with CRUD UI with very little business logic.

Being the first time with EF, I developed this project by creating and holding an instance of objectContext in the layout form (the main form or the one that appears as the application for the user) as a member variable and bound the request to the View grid.

For various events, such as clicks on the ribbon bar buttons, clicks on grid lines, etc., I open a different window shape. In this window form, I create another object context and save it in a member variable of this form class.

I read some blogs and questions like:

One set of authors offers to exchange the context of the object, while others offer short-lived and not common.

I have reached such a state of confusion, because now I am in a state where the changes that I made to objectContext in one of the child forms do not reflect the parent form that showed it. I tried to upgrade, but still nothing useful. For the experiment only, I shared the objectContext, which I first created in the parent class itself through constructor injection, and my problem of reflecting changes has been resolved.

It is a huge job for me to convert all my child forms to share an objectContext. But I'm ready if it's worth it. I'm not sure what the hidden problems of sharing it will be?

I can select a static instance of objectContext, because I do not use it for the Web and do not plan multithreaded scripts. If necessary, I can go up to one single.

My questions:

  • To share or not share the ObjectContext for my situation?
  • If not shared, how can I solve my current problem of updating one objectContext with changes made to others?
  • If to share - what would be better? Static or singleton or something else?

Details of the project and environment are given below:

  • Winforms
  • WITH#
  • VS 2012
  • EF 4.0, a model created using the first data approach.

I publish this after searching and reading many questions and blog posts. The more I read, the more confusing it becomes :) Please carry me if I leave someone to take on something to answer. I will try to update the question if such clarifications are asked using comments.

+6
source share
1 answer

Your questions

To share or not share the ObjectContext for my situation? Do not share your context. The EntityFramework context must follow the UnitOfWork pattern. The context of your object should be as short as possible, without the need to create / destroy too many contexts. This usually refers to the individual “operations” in your application as units of work. For a web application / api, it can be for HttpWebRequest , or you can do it for the operation of logical data (for each of the implemented parts of the "Business Logic").

For instance:

  • LoadBusinssObjects() will create a context, load your list of data and any data associated with it, and then delete the context.
  • CreateBusinessObject() will create a context, create an instance of some object, fill it with data, bind it to collection in the context, save the changes and delete the context.
  • UpdateBusinessObject() will read some object from the context, update it, save changes and delete the context.
  • DeleteBusinessObject() will find the business object in the context, delete it from the collection in the context, save the changes, and delete the context.

If not shared, how can I solve my current problem of updating one objectContext with changes made to others? This is a job for pub / sub architecture . It can be as simple as several static event handlers on your objects for each operation described above. Then, in your code for each business transaction, you fire up the corresponding events.

If to share - what would be better? Static or singleton or something else? This is not true. The EF context will continue to grow in memory, as the context manager continuously collects cached objects (both attached and unconnected) for each individual interaction that you make in your application. The context is not intended to work as follows.

In addition to using resources, the EF context is not thread safe. For example, what if you want one of the forms in your editor to save some changes at the same time that the tree list loads some new data? With one static instance, it’s better to make sure that all this works in the user interface thread or synchronized with the semaphore (yuck and yuck - bad practice).

Example

Here is an example of using C # and the first approach code according to your post. Please note: I am not considering things like data concurrency or threading so that this example is short. Also in a real application, this concept is implemented using generics and reflections, so that ALL of our models have basic events for them to create, update, delete.

 public class MyCodeFirstEntityChangedArgs : EventArgs { /// <summary> /// The primary key of the entity being changed. /// </summary> public int Id {get;set;} /// <summary> /// You probably want to make this an ENUM for Added/Modified/Removed /// </summary> public string ChangeReason {get;set;} } public class MyCodeFirstEntity { public int Id {get;set;} public string SomeProperty {get;set;} /// <summary> /// Occurs when an instance of this entity model has been changed. /// </summary> public static event EventHandler<MyCodeFirstEntityChangedArgs> EntityChanged; } public class MyBusinessLogic { public static void UpdateMyCodeFirstEntity(int entityId, MyCodeFirstEntity newEntityData) { using(var context = new MyEFContext()) { // Find the existing record in the database var existingRecord = context.MyCodeFirstEntityDbSet.Find(entityId); // Copy over some changes (in real life we have a // generic reflection based object copying method) existingRecord.Name = newEntityData.Name; // Save our changes via EF context.SaveChanges(); // Fire our event handler so that other UI components // subscribed to this event know to refresh/update their views. // ---- // NOTE: If SaveChanges() threw an exception, you won't get here. MyCodeFirstEntity.EntityChanged(null, new MyCodeFirstEntityChangedArgs() { Id = existingRecord.Id, ChangeReason = "Updated" }); } } } 

Now you can attach event handlers to your model from anywhere (its static event handler) as follows:

MyCodeFirstEntity.EntityChanged += new EventHandler<MyCodeFirstEntityChangedArgs>(MyCodeFirstEntity_LocalEventHandler);

and then a handler in each view, which will update the local user interface views each time this event fires:

 static void MyCodeFirstEntity_LocalEventHandler(object sender, MyCodeFirstEntityChangedArgs e) { // Something somewhere changed a record! I better refresh some local UI view. } 

Now, every user interface component that you have can subscribe to what events are important to it. If you have a list of trees, and then some form of editor, the list of trees will subscribe to any changes to add / update / delete node (or a simple way - just update the list of the whole tree).

Cross-Application Updates

If you want to take another step and even bind individual instances of your application in a connected environment, you can implement a pub / sub-event system on the network using something like WebSync - a comet implementation for the Microsoft technology stack . WebSync has everything that was built in to split events into logical “channels” for each object / event you want to subscribe to or publish to. And yes, I work for a software company that makes WebSync - they pay for my time when I write this. :-)

But if you do not want to pay for a commercial implementation, you can write your own client / server for the TCP socket, which distributes notifications for the above events when the entity changes. Then, when the subscribed application receives a notification over the network, it can launch its local event handlers in the same way, which will lead to the updating of local views. You cannot do this with a poorly archived static instance of your data context (you will only have one instance of your application). With some good settings at an early stage, you can easily hide in the distributed pub-sub system later, which works simultaneously with several instances of native applications and web applications! It is becoming very powerful.

+6
source

All Articles