Binding objects

Db4o adds additional flexibility to its reference system allowing the user to re-associate an object with its stored instance or to replace an object in database:

c#:

IExtObjectContainer#Bind(object,id)

VB:

IExtObjectContainer#Bind(object,id)

Typical usecases could be:

The following requirements should be met:

Calling ExtObjectContainer#bind(object,id) does not have any impact on persisted objects. It only attaches the new object to the database identity. ObjectContainer#set(object) should be used to persist the change.

Let's look how it works in practice.

IdentityExample.cs: TestBind
01private static void TestBind() 02 { 03 SetObjects(); 04 IObjectContainer db = Db4oFactory.OpenFile(Db4oFileName); 05 try 06 { 07 IQuery q = db.Query(); 08 q.Constrain(typeof(Car)); 09 q.Descend("_model").Constrain("Ferrari"); 10 IObjectSet result = q.Execute(); 11 Car car1 = (Car)result[0]; 12 long IdCar1 = db.Ext().GetID(car1); 13 Car car2 = new Car("BMW", new Pilot("Rubens Barrichello")); 14 db.Ext().Bind(car2,IdCar1); 15 db.Set(car2); 16 17 result = db.Get(typeof(Car)); 18 ListResult(result); 19 } 20 finally 21 { 22 db.Close(); 23 } 24 }
IdentityExample.vb: TestBind
01Private Shared Sub TestBind() 02 SetObjects() 03 Dim db As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 04 Try 05 Dim q As IQuery = db.Query() 06 q.Constrain(GetType(Car)) 07 q.Descend("_model").Constrain("Ferrari") 08 Dim result As IObjectSet = q.Execute() 09 Dim car1 As Car = CType(result(0), Car) 10 Dim IdCar1 As Long = db.Ext().GetID(car1) 11 Dim car2 As Car = New Car("BMW", New Pilot("Rubens Barrichello")) 12 db.Ext().Bind(car2, IdCar1) 13 db.Set(car2) 14 15 result = db.Get(GetType(Car)) 16 ListResult(result) 17 Finally 18 db.Close() 19 End Try 20 End Sub

So this method gives you control over internal object storage. But its usage is potentially dangerous and normally should be avoided. Let's look at an example how bind can damage your object consistency:

Imagine three objects referencing eachother:

a1 => b1 => c1

Now if you call #bind() to replace b1 with b2 in memory you will get the following:

a1 => b1 => c1
b2 => c1

b2 will be the new in-memory copy of the persistent object formerly known as b1.
a1 will still point to b1 which is now a transient object.
If you now store a1, you will get a duplicate copy of b1 stored.

Please, remember this scenario and use ExtObjectContainer#bind(object,id) only for short-lived objects and in controlled situations where no other references exist.

For the scenarios, which merging disconnected transient object, please refer to Merge Module project suggested design.