Using objects across scopes

Thread is closed for posting
8 posts, 1 answers
  1. Stuart Hemming
    Stuart Hemming avatar
    1622 posts
    Member since:
    Jul 2004

    Posted 21 Jul 2010 Link to this post

    I've got a project that I've created some persistent classes in using OA.

    My project has a master page in which I create a Scope for the page using it.

    I also have a base class for my UserControls that does the same thing.

    I've just written some code that, on a page, starts a transaction, updates the properties of a class (School) on that page and commits the changes to the DB. All good so far.

    I've changed the code to update another property in the School instance, which is, in turn is another persistent class (Lesson). If I fetch an instance of  Lesson from the DB in the page and update School with it, everything works.

    If, however, I use a method in my UserControl - specially written for the task - to return an Lesson instance my attempt commit the changes to School fails with an error... 

    Telerik.OpenAccess.Exceptions.InvalidOperationException was unhandled by user code
      Message="Object references between two different object scopes are not allowed. The object 'RSD.Model.Lesson' is already managed by 'ObjectScopeImpl 0x31d273f Telerik.OpenAccess.RT.ObjectScope' and was tried to be managed again by 'ObjectScopeImpl 0x24d7226 Telerik.OpenAccess.RT.ObjectScope'."
      Source="Telerik.OpenAccess"
      CanRetry=true
      StackTrace:
           at Telerik.OpenAccess.SPI.Backends.ThrowException(Exception e)
           at Telerik.OpenAccess.RT.ExceptionWrapper.Throw()
           at OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp.handleException(Exception x)
           at OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp.internalCommit(Boolean phase)
           at OpenAccessRuntime.DataObjects.OpenAccessPersistenceManagerImp.commit()
           at OpenAccessRuntime.DataObjects.UnsynchronizedPMProxy.commit()
           at Telerik.OpenAccess.RT.TransactionImpl.Commit()
           at RSD.Website.Controls.LessonDetailsView.dv_ItemUpdating(Object sender, DetailsViewUpdateEventArgs e) in c:\Users\Stuart\Documents\Visual Studio 2008\WebSites\RSD\Controls\School\LessonDetailsView.ascx.cs:line 120
           at System.Web.UI.WebControls.DetailsView.OnItemUpdating(DetailsViewUpdateEventArgs e)
           at System.Web.UI.WebControls.DetailsView.HandleUpdate(String commandArg, Boolean causesValidation)
           at System.Web.UI.WebControls.DetailsView.HandleEvent(EventArgs e, Boolean causesValidation, String validationGroup)
           at System.Web.UI.WebControls.DetailsView.OnBubbleEvent(Object source, EventArgs e)
           at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
           at System.Web.UI.WebControls.DetailsViewRow.OnBubbleEvent(Object source, EventArgs e)
           at System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args)
           at System.Web.UI.WebControls.Button.OnCommand(CommandEventArgs e)
           at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
           at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
           at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
           at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
           at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
      InnerException:

    So, to the question; how can I have multiple UserControls that can return an instance of a persistent class to either a page or another UserControl such that the receiver can update an instance of another class with the received value?

    -- 
    Stuart
  2. Answer
    Steve
    Steve avatar
    1888 posts
    Member since:
    Dec 2008

    Posted 21 Jul 2010 Link to this post

    I usually have a Helper in App_Code which creates an instance of ObjectScopeProvider1.GetPerRequestScope() ...then just use that everywhere I need and dispose in Page_Unload in my masterpage.
  3. Stuart Hemming
    Stuart Hemming avatar
    1622 posts
    Member since:
    Jul 2004

    Posted 21 Jul 2010 Link to this post

    Sweet!

    What I did was change my BasePage and BaseUserControl classes to read...

    IObjectScope scope = RSDScopeProvider.GetPerRequestScope(HttpContext.Current);
     
    public IObjectScope Scope
    {
        get
        {
            return scope;
        }
        set
        {
            scope = value;
        }
    }

    There are bucketloads of things about this product that I haven't a clue about. This is one less.

    Thanks a lot.

    -- 
    Stuart
  4. Stuart Hemming
    Stuart Hemming avatar
    1622 posts
    Member since:
    Jul 2004

    Posted 27 Jul 2010 Link to this post

    If anyone from the OA documentation team is listening, this is definitely one for the "How-to" section.

    -- 
    Stuart
  5. Steve
    Steve avatar
    1888 posts
    Member since:
    Dec 2008

    Posted 27 Jul 2010 Link to this post

    I think they're moving away from it since that's the "old" model for doing things

    The new Context\Designer doesn't seem to have a PerRequest method (as far as I can see anyway)
  6. Stuart Hemming
    Stuart Hemming avatar
    1622 posts
    Member since:
    Jul 2004

    Posted 27 Jul 2010 Link to this post

    Steve,

    I'm glad you posted that before I started recreating my project!

    Telerik,
    Is Steve right? Is there just a different method name or a different way of doing things? Or has this, quite important, bit of functionality gone?

    -- 
    Stuart
  7. Steve
    Steve avatar
    1888 posts
    Member since:
    Dec 2008

    Posted 27 Jul 2010 Link to this post

    I don't think it's GONE, I just don't think it's BUILT IN in this version since there's no ObjectScopeProvider

    I think you could just rip that method in ObjectScopeProvider out to App_Code and replace the "Scope" with a "Context" since they're essentially the same thing, but the context API is so much more user friendly.

  8. Pencho
    Admin
    Pencho avatar
    22 posts

    Posted 27 Jul 2010 Link to this post

    Hi Stuart Hemming,

    Steve is right, currently this code is not automatically generated when a domain model is used but you can put it in a helper class and use it with a context.

    And thank you for the suggestion, this will be definitely turned into a How-to topic in the OpenAccess documentation. If you have any other suggestions about how the OpenAccess documentation could be improved, or if you find any missing content, we would appreciate if you share that with us. 

    Greetings,
    Pencho
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Back to Top