Load a single object?

7 posts, 1 answers
  1. Sphengle
    Sphengle avatar
    29 posts
    Member since:
    Sep 2007

    Posted 19 Nov 2009 Link to this post

    I'm new to this ORM but have so far spent many hours looking into it and trying it.  Yet I can find no code examples that populate a single entity from the database.  I can add new ones easily.  But to retrieve, modifiy and save - well I'm missing the first bit.  I've assumed it had something to do with the scope.Refresh() method - but this doesn't seem to do anything.  I thought if I set the ID correctly and called scope.Refresh() it would retrieve it from the database - it doesn't.

    How do you do this simple thing?
  2. Sphengle
    Sphengle avatar
    29 posts
    Member since:
    Sep 2007

    Posted 19 Nov 2009 Link to this post

    Well - I've found out how to do it.  It's a bit long winded.  Had to go to another website to find out how.

     


     Currency c = (Currency)scope.GetObjectById(Database.OID.ParseObjectId(typeof(Currency), "2"));  

     

    Considering this is such a simple thing to do I'm surprised I've been unable to find anything explaining how to do it on the Telerik website.  So far, I've been massively put off by OpenAccess ORM.


  3. DevCraft banner
  4. Answer
    PetarP
    Admin
    PetarP avatar
    754 posts

    Posted 20 Nov 2009 Link to this post

    Hello Sphengle,

    That is just one way to retrieve a record based on its ID. You can also perform a query (Linq,SQL or OQL one) to retrieve the record from the database that matches the passed ID. Here is an example with LINQ:
    int catId = 1;
              IObjectScope scope = ObjectScopeProvider1.GetNewObjectScope();
              Category ct = (from c in scope.Extent<Category>()
                            where c.CategoryID == catId
                            select c).First();
              Console.WriteLine(ct.Description);

    The Refresh method is used to refresh a persistent object that has already been retrieved from the database. Imagine the following situation:
    User A: retrieves a category object with id equals 1 and freight equals 10 and starts performing some business logic.
    User B: retrieves the same category object changes its freight to 11 and commits it to the database.

    In that situation User A would still have the freight value of his category object set to 10. Unless he does a refresh before committing this would raise a concurrent exception. If he however does a refresh before committing the freight value of his category object will be set to 11.


    Kind regards,
    Petar
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  5. Sphengle
    Sphengle avatar
    29 posts
    Member since:
    Sep 2007

    Posted 20 Nov 2009 Link to this post

    Thanks for the detailed reply.  However, the method of getting a single entity is far more complicated than what we are currently doing.  For this and other reasons I regret that it looks like after the trial we will not be purchasing.
  6. PetarP
    Admin
    PetarP avatar
    754 posts

    Posted 20 Nov 2009 Link to this post

    Hello Sphengle,

    You can always implement a generic helper method to ease the retrieving of the objects. For example you can implement a method like:
    private static T GetObjectByItsID<T>(IObjectScope scope, object value)
           {
               T objectToReturn = (T)scope.GetObjectById(Database.OID.ParseObjectId(typeof(T), value.ToString()));
               return objectToReturn;
           }

    Now you will be able to use this method in your code to retrieve all kind of objects using theirs ID using something similar to this:
    Category ct = GetObjectByItsID<Category>(scope, 1);           
               Order ord = GetObjectByItsID<Order>(scope, 10249);

    Note that a generic way of retrieving object based on their ID will be introduced with one of our next service packs/internal builds.
    Can you please share with us the other obstacles you have faced with Telerik OpenAccess ORM so that we can address them?

    Greetings,
    Petar
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  7. Sphengle
    Sphengle avatar
    29 posts
    Member since:
    Sep 2007

    Posted 20 Nov 2009 Link to this post

    There are many things I like about the ORM but following would make it much better...

    1. If you add a new column to a DB it only regenerates the private field in the generated class.  You have to manually add the accessors in the other partial class.

    2.  I can't see any support for SQL server side paging. E.g. SubSonic has a Query and SqlQuery object that you can give pageindex and page sizes to.  It will then, behind the scenes, generate paged Sql statements.  This is quite important to us since we have > 100,000 records in one DB.

    3 - I have a DB with Orders having many OrderItems.  I've seen some of the sample code (SampleBusinessApplication) have something like a IList<OrderDetail> property in the Order class.  I suspected this had something to do with the "advanced" section of the wizard?  I couldn't figure out how to use the "add reference" bit. 

    4 - The OrderItems do have an Order property.  I suspect this is not lazy loaded?
  8. PetarP
    Admin
    PetarP avatar
    754 posts

    Posted 23 Nov 2009 Link to this post

    Hi Sphengle,

    1. The accessors are intentionally left unchanged. This is done in order to prevent the loss of any changes you might have done in the public declaration. The complete public declaration (including the accessors for the newly added fields) is generated in the private part of the partial class as commented code at the bottom. You only need to copy it and override the public declarations.
    As another approach you can disable the generation of partial classes. This way both the private declaration and the accessors will be generated in a single file that will be always overwritten.

    2. Our DataSource control provides you with an option of server side paging. If you however do not want/need to use the DataSource control you can always implement your own way of paging using either Linq or OQL (assuming you do not want to use plain SQL).
    Here are two samples:
    Linq:
    scope.Transaction.Begin();
    var result = (from c in scope.Extent<Order>()
    where c.Freight < 100
    select c).Skip(100).Take(10);
    OQL:
    IQuery oqlQuery = scope.GetOqlQuery("Select * from OrderExtent");
    oqlQuery.MaxResultCount = 10;
    oqlQuery.Skip= 100;
    IQueryResult result = oqlQuery.Execute();

    3. Yes, you are correct. You will need to navigate to the Advanced tab in the reverse mapping wizard. Expand the OrderItems class and select the order field. Check the checkbox for create one-to-many list. This will create a list of OrderItems in your Order class.

    4. When you retrieve an Order object its properties are not loaded until they are needed (accessed). This is called lazy loading. Having that in mind, the collection of OrderItems is not loaded as well. When the first property of the Order class is accessed, the Order class is loaded but none of the OrderItems objects are loaded (assuming that the default fetchplan is in place). When you access the OrderItems collection then all the OrderItems objects that belong to the given order will be retrieved and they will automatically "know" its Order.

    Best wishes,
    Petar
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Back to Top
DevCraft banner