Ask a questionAsk a question
 

Proposed AnswerDataServiceContext stored in session - cannot serialize

  • Wednesday, October 28, 2009 6:40 PMmschumacker Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    We have an application that uses the ADO Data services.  The use of these services has been great and really helped us develop our product quickly.  What we have been doing, though, is storing our dataContext in Session of our ASP.NET app.  Each session (user) gets their own copy of the dataContext which makes for less trips as it is caching the information and retrieving it only once.

    This has worked great for us, until now.  We have a need to push Session out to Sql Server and therefore need to make sure that all our classes are Serializable.  I am able to make most of the classes this, including my dataContext class, however since it is inheriting from DataServiceContext, it fails.  DataServiceContext is not serializable.

    Any ideas on what to do here.  I was hoping to keep the dataContext in Session, however it's not looking good.  That will cause me to rewrite a bunch of code and will definitely cause multiple trips to the database and back if I can't keep it in Session.

    I appreciate any and all help on this.
    Matt

All Replies

  • Thursday, October 29, 2009 10:49 AMBineesh AV Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    DataServiceContext wont cache any data. you can create a new instance any time and use it.

    Thanks & Regards

    Bineesh AV
  • Thursday, October 29, 2009 12:29 PMmschumacker Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    But it is caching the data.  If I make a request for the same object twice, it doesn't complete a round trip getting it the second time, unless I specifically ask  it to reload.  And here's the issue. 

    I have Page1.aspx get an object from the database that has children objects of various types.  I then store that object, plus the dataServiceContext in session then redirect to Page2.aspx.  Page2.aspx updates variables on the first object, plus adds new children objects.  The code currently pulls the parent out of Session, updates this object and calls dataServiceContext.UpdateObject() method.  Plus any new additions are added to the dataServiceContext via the AddToXXXX() method, and the appropriate AddLink called also.

    After all that, I can simply call SaveChanges and everythign works wonderfully.

    Now, if I can't store my dataServiceContext in session I have to make more round trips to the database.  The context can only update objects that it knows about.  So if I have to create a new dataServiceContext for my update, this is a hassle.  Here's the difference.

    Now on Page2.aspx, I cannot use my object stored in Session to perform any updates, since I have to make all updates within the context of one post-back.  I will have to create a new instance of my dataServiceContext, then re-retrieve an object that I already have, perform all my updates, additions and new links, and then perform my SaveChanges().  This parent object currently has 5 lists of children objects and each would need to be retrieved for each update.  This now becomes way more complex with too many round-trips to the database. 

    If I have to retrieve an object everytime from the database anytime I want to update the object, how is this efficient???  Why can't I store this in Session and then simply update the attributes that I need to, then perform my SaveChanges().

    So, if this is true, and I have an object that, lets say, have 60 columns of data but I simply need to update 1.  I would need to retrieve the object from the database (even though I have a copy that I retrieved earlier), then update the one attribute and send it back. 

    How is this better than simply using smarter WCF Services?  This has worked great up to this point with the ability to store  my dataServiceContext in Session as I'm using InProc.  But now that I have a need to push this out to SQL Server, I'm hosed.

    Is it just me and that I'm using the ADO Data Services incorrectly?  Should this be the way that they are used?  Caching data is a big piece of any ORM as it should be.

    I greatly appreciate any and all thoughts on this.
    Matt


  • Monday, November 02, 2009 2:30 PMmschumacker Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Anybody??  Is this thing on???  bueller?  bueller?  bueller?  bueller?
  • Wednesday, November 04, 2009 4:39 PMDave Russell Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Whilst this has been working for you up to now, I think you have realised this isn't a good solution.

    See here for recommendations on Context lifetime.  This related to EF, but equally applies to DataService Context.

    Dave
  • Thursday, November 05, 2009 7:24 PMPeter Qian - MSFTAnswererUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Proposed Answer
    Hello Matt,

    I'm afraid that the above posts are correct in that we designed the data service context to be short-lived objects. It wasn't our intention for it to be used to track large amount of entities over the entire life span of the application. Moreover, although we do cache entities locally, every time you enumerate through a query, the context will still hit the server, then we do merging depending on your context's merge options. So unless you specifically query the local entities (http://blogs.msdn.com/peter_qian/archive/2009/04/23/working-with-local-entities-in-astoria-client.aspx), you will not save a lot of bandwidth by maintaining the same context in the session.

    That said, if your client-side entities are serializable, you can go through ctx.Entities and serialize all of them, and later on attach the entities back via ctx.AttachTo. You'll also need to know the entity set name. This method is hacky because you lose all client side state information stored in the entity descriptors, and you lose the links. You can design your own storage items for the links but there isn't much you can do about the entity descriptors - since there is no good way to re-attach a descriptor.

    We do have plans to make entity descriptor serializable, but that's really just an idea. Until then, you'll have to play some tricks to maintain the state info on the client. Or, like the posts above suggested, revise your design on context lifetime management.

    Regards,
    PQ

    Peter Q. http://blogs.msdn.com/peter_qian