How to perform an upsert on a collection of data

7 posts, 0 answers
  1. Brendan Enrick
    Brendan Enrick avatar
    28 posts
    Member since:
    Jul 2009

    Posted 04 Dec 2009 Link to this post

    I have a collection of objects that I want to upsert (update if exists and insert if not exists) into the database.

    I am not finding how to do this with OpenAccess. I'd like to have a transaction which can perform this operation for me. Is there an easy way to do this or do I have to pull them all back from the database in order to update them?

    Thanks,
    Brendan
  2. Damyan Bogoev
    Admin
    Damyan Bogoev avatar
    581 posts

    Posted 08 Dec 2009 Link to this post

    Hello Brendan Enrick,

    To achieve this you could do the following:

     
    scope.TransactionProperties.AutomaticBegin = true;
    Upsert(scope, listOfObjects);
    public static void Upsert(IObjectScope scope, List<Object> objects)
    {
        foreach (Object obj in objects)
        {
           if (scope.GetObjectId(obj) == null)
           {
              scope.Add(obj);
           }  
        }
        scope.Transaction.Commit();
    }
    The IObjectScope.GetObjectId() method returns the database identity for a persistent object. When a new object is passed to the method, null is returned. Note that the updated objects should be loaded from the same object scope. Otherwise their changes will not be persisted on Commit(). Hope that helps.

    Regards,
    Damyan Bogoev
    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.
  3. DevCraft banner
  4. Ashley
    Ashley avatar
    30 posts
    Member since:
    Nov 2012

    Posted 21 Nov 2012 Link to this post

    Hi,

    This seems to be the right place for this.

    If I use the method below, my objects are always inserted. I'm using the following code:
    using (var context = new FluentModelContext()) {
                    context.UpdateSchema();
     
                    var t1 = new Test1();
                    t1.Id = 1;
                    t1.col1 = "value";
                    t1.col2 = "newValue";
     
                    var t2 = new Test2();
                    t2.test1 = t1;
                    t2.t2compkey = "part2";
     
                    var scope = context.Scope.Database.GetObjectScope();
                    scope.TransactionProperties.AutomaticBegin = true;
                    FluentModelContext.Upsert(scope, new List<object>{ t1, t2 });
                }
     
    public static void Upsert(IObjectScope scope, List<Object> objects) {
                foreach (Object obj in objects) {
                    if (scope.GetObjectId(obj) == null) {
                        scope.Add(obj);
                    }
                }
                scope.Transaction.Commit();
            }

    The objects are never being found by the method GetObjectId.

    Regards,
    Ashley
  5. PetarP
    Admin
    PetarP avatar
    754 posts

    Posted 24 Nov 2012 Link to this post

    Hello Ashley,

     The objects are still new to the context (scope) and thus their identity is not actually known. Even though you have added the ID manually they are still marked as new and as such the GetObjectID will not return anything as they are considered to be fresh new objects.

    Greetings,
    Petar
    the Telerik team
    Telerik OpenAccess ORM Meets ASP.NET Web API. Read more.
  6. Ashley
    Ashley avatar
    30 posts
    Member since:
    Nov 2012

    Posted 26 Nov 2012 Link to this post

    Hi Petar,

    Thanks for your reply.

    Is attaching the objects (AttachCopy) a good alternative to achieve this functionality?

    Regards,
    Ashley
  7. PetarP
    Admin
    PetarP avatar
    754 posts

    Posted 29 Nov 2012 Link to this post

    Hello Ashley,

     Yes attach objects should do the trick for you. What it does is it basically attaches an object to our context which will intern "search for its match" in our internal states. If such match is found the object will be updated instead of inserted. If the object is not found it will be inserted.
    I believe this is the functionality you have been trying to achieve with the id check. 

    Kind regards,
    Petar
    the Telerik team
    Telerik OpenAccess ORM Meets ASP.NET Web API. Read more.
  8. Ashley
    Ashley avatar
    30 posts
    Member since:
    Nov 2012

    Posted 29 Nov 2012 Link to this post

    Hi Petar,

    Yes it is, thanks. I think you should mark this question as solved as AttachCopy is the right method to achieve the OP's required functionality.

    Regards,
    Ashley
Back to Top
DevCraft banner