Question

I am wondering what is the standard practice for how DataServiceContext instances should be used. If I have a class that has multiple methods in it that need to perform operations on the context should I create a new instance of the context inside each method, or have the context be a single member of the class which is shared by all the methods?

I am asking this because I recently saw a comment made by another developer in some code I am working on that mentioned the need to recreate the context after adding some objects and before performing some more operations on it.

i.e. Should I be doing this:

public class ServiceHelper
{
  public void DoSomething()
  {
    DataContext ctx = new DataContext(Uri);

    //do something with the context and call SaveChanges()
  }

  public int GetSometing()
  {
    DataContext ctx = new DataContext(Uri);

    return ctx.GetSomething();
   }
}

or this:

public class ServiceHelper
{
  private readonly DataContext _ctx = new DataContext(Uri);

  public void DoSomething()
  {
    //do something with _ctx and call SaveChanges()
  }

  public int GetSomething()
  {
    return _ctx.GetSomething();
  }
}

?

Also I should add that this is in the context of an ASP.NET MVC application so the ServiceHelper class here is going to be reconstructed on each page request.

EDIT

Ok so it seems like either would technically valid according to Msft, as these are short lived classes, but I am still wondering if both are equally "safe" and equivalent. i.e. if I add/update some entities and call SaveChanges, then potentially a separate application makes an update to the same entities and then I retrieve those entities again using the same context instance is everything going to behave the same as if I had instead created a new context before my second operation?

CONCLUSION

I just found this and I think it helps explain the difference:

By default, the client only materializes an entry in the response feed into an object for entities that are not already being tracked by the DataServiceContext. This means that changes to objects already in the cache are not overwritten. This behavior is controlled by specifying a MergeOption value for queries and load operations. This option is specified by setting the MergeOption property on the DataServiceContext. The default merge option value is AppendOnly. This only materializes objects for entities that are not already being tracked, which means that existing objects are not overwritten. Another way to prevent changes to objects on the client from being overwritten by updates from the data service is to specify PreserveChanges. When you specify OverwriteChanges, values of objects on the client are replaced by the latest values from the entries in the response feed, even if changes have already been made to these objects.

So it looks like if I update some entities and then a separate application makes further changes and then I retrieve those entities again using the same DataServiceContext instance then it depends on what the MergeOption is set to whether I will get the entities in the state that they are in the database or just in the state that I last had them locally.

Was it helpful?

Solution

Msdn says it

In general, a DataContext instance is designed to last for one "unit of work" however your application defines that term. A DataContext is lightweight and is not expensive to create. A typical LINQ to SQL application creates DataContext instances at method scope or as a member of short-lived classes that represent a logical set of related database operations.

Providing of course you use LINQ to SQL. But even in other technologies/libraries context is usually a very lightweight object. In most cases physical connection is not torn down (but a logical is). I'd guess your concern is to do with connection pooling, so as long as you use one (which you should) then just follow msdn recommendation. So

public void DoSomething()
{
    using(DataContext ctx = new DataContext(Uri))
    {
         //do something with the context and call SaveChanges()
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top