This is a migrated thread and some comments may be shown as answers.

How to perform an upsert on a collection of data

6 Answers 426 Views
LINQ (LINQ specific questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Brendan Enrick
Top achievements
Rank 1
Brendan Enrick asked on 04 Dec 2009, 03:32 PM
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

6 Answers, 1 is accepted

Sort by
0
Damyan Bogoev
Telerik team
answered on 08 Dec 2009, 04:42 PM
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.
0
Ashley
Top achievements
Rank 1
answered on 21 Nov 2012, 10:06 AM
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
0
PetarP
Telerik team
answered on 24 Nov 2012, 02:15 PM
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.
0
Ashley
Top achievements
Rank 1
answered on 26 Nov 2012, 06:53 AM
Hi Petar,

Thanks for your reply.

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

Regards,
Ashley
0
PetarP
Telerik team
answered on 29 Nov 2012, 03:49 PM
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.
0
Ashley
Top achievements
Rank 1
answered on 30 Nov 2012, 05:06 AM
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
Tags
LINQ (LINQ specific questions)
Asked by
Brendan Enrick
Top achievements
Rank 1
Answers by
Damyan Bogoev
Telerik team
Ashley
Top achievements
Rank 1
PetarP
Telerik team
Share this question
or