Deleting Structured Objects

As we have already seen, we call delete() on objects to get rid of them.

StructuredExample.cs: DeleteFlat
1private static void DeleteFlat(IObjectContainer db) 2 { 3 IObjectSet result = db.Get(new Car("Ferrari")); 4 Car found = (Car)result.Next(); 5 db.Delete(found); 6 result = db.Get(new Car(null)); 7 ListResult(result); 8 }

StructuredExample.vb: DeleteFlat
1Private Shared Sub DeleteFlat(ByVal db As IObjectContainer) 2 Dim result As IObjectSet = db.Get(New Car("Ferrari")) 3 Dim found As Car = DirectCast(result.Next(), Car) 4 db.Delete(found) 5 result = db.Get(New Car(Nothing)) 6 ListResult(result) 7 End Sub

Fine, the car is gone. What about the pilots?

StructuredExample.cs: RetrieveAllPilotsQBE
1private static void RetrieveAllPilotsQBE(IObjectContainer db) 2 { 3 Pilot proto = new Pilot(null, 0); 4 IObjectSet result = db.Get(proto); 5 ListResult(result); 6 }

StructuredExample.vb: RetrieveAllPilotsQBE
1Private Shared Sub RetrieveAllPilotsQBE(ByVal db As IObjectContainer) 2 Dim proto As Pilot = New Pilot(Nothing, 0) 3 Dim result As IObjectSet = db.Get(proto) 4 ListResult(result) 5 End Sub

Ok, this is no real surprise - we don't expect a pilot to vanish when his car is disposed of in real life, too. But what if we want an object's children to be thrown away on deletion, too?

Recursive Deletion 

The problem of recursive deletion (and its solution, too) is quite similar to the update problem. Let's configure db4o to delete a car's pilot, too, when the car is deleted.

StructuredExample.cs: DeleteDeepPart1
1private static IConfiguration DeleteDeepPart1() 2 { 3 IConfiguration configuration = Db4oFactory.NewConfiguration(); 4 configuration.ObjectClass(typeof(Car)).CascadeOnDelete(true); 5 return configuration; 6 }

StructuredExample.vb: DeleteDeepPart1
1Private Shared Function DeleteDeepPart1(ByVal db As IObjectContainer) As IConfiguration 2 Dim configuration As IConfiguration = Db4oFactory.NewConfiguration() 3 configuration.ObjectClass(GetType(Car)).CascadeOnDelete(True) 4 Return configuration 5 End Function

StructuredExample.cs: DeleteDeepPart2
1private static void DeleteDeepPart2(IObjectContainer db) 2 { 3 IObjectSet result = db.Get(new Car("BMW")); 4 Car found = (Car)result.Next(); 5 db.Delete(found); 6 result = db.Get(new Car(null)); 7 ListResult(result); 8 }

StructuredExample.vb: DeleteDeepPart2
1Private Shared Sub DeleteDeepPart2(ByVal db As IObjectContainer) 2 Dim result As IObjectSet = db.Get(New Car("BMW")) 3 Dim found As Car = DirectCast(result.Next(), Car) 4 db.Delete(found) 5 result = db.Get(New Car(Nothing)) 6 ListResult(result) 7 End Sub

Again: Note that all configuration must take place before the ObjectContainer is opened.

Another way to organize cascaded deletion is using callbacks. The callbacks allow you to specify explicitly, which objects are to be deleted.

Recursive Deletion Revisited

But wait - what happens if the children of a removed object are still referenced by other objects?

StructuredExample.cs: DeleteDeepRevisited
01private static void DeleteDeepRevisited(IObjectContainer db) 02 { 03 IObjectSet result = db.Get(new Pilot("Michael Schumacher", 0)); 04 Pilot pilot = (Pilot)result.Next(); 05 Car car1 = new Car("Ferrari"); 06 Car car2 = new Car("BMW"); 07 car1.Pilot = pilot; 08 car2.Pilot = pilot; 09 db.Set(car1); 10 db.Set(car2); 11 db.Delete(car2); 12 result = db.Get(new Car(null)); 13 ListResult(result); 14 }

StructuredExample.vb: DeleteDeepRevisited
01Private Shared Sub DeleteDeepRevisited(ByVal db As IObjectContainer) 02 Dim result As IObjectSet = db.Get(New Pilot("Michael Schumacher", 0)) 03 Dim pilot As Pilot = DirectCast(result.Next(), Pilot) 04 Dim car1 As Car = New Car("Ferrari") 05 Dim car2 As Car = New Car("BMW") 06 car1.Pilot = pilot 07 car2.Pilot = pilot 08 db.Set(car1) 09 db.Set(car2) 10 db.Delete(car2) 11 result = db.Get(New Car(Nothing)) 12 ListResult(result) 13 End Sub

StructuredExample.cs: RetrieveAllPilots
1private static void RetrieveAllPilots(IObjectContainer db) 2 { 3 IObjectSet results = db.Get(typeof(Pilot)); 4 ListResult(results); 5 }

StructuredExample.vb: RetrieveAllPilots
1Private Shared Sub RetrieveAllPilots(ByVal db As IObjectContainer) 2 Dim results As IObjectSet = db.Get(GetType(Pilot)) 3 ListResult(results) 4 End Sub

Currently db4o does not check whether objects to be deleted are referenced anywhere else, so please be very careful when using this feature.However it is fairly easy to implement referential checking on deletion using deleting() callback. See Callbacks chapter for more information.