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.
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
}
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.