Deleting Structured Objects

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

StructuredExample.cs: DeleteFlat
1public 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
1Public 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
1public 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
1Public 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
1public static void DeleteDeepPart1(IObjectContainer db) 2 { 3 Db4oFactory.Configure().ObjectClass(typeof(Car)) 4 .CascadeOnDelete(true); 5 }

StructuredExample.vb: DeleteDeepPart1
1Public Shared Sub DeleteDeepPart1(ByVal db As IObjectContainer) 2 Db4oFactory.Configure().ObjectClass(GetType(Car)).CascadeOnDelete(True) 3 End Sub

StructuredExample.cs: DeleteDeepPart2
1public 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
1Public 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
01public 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
01Public 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
1public static void RetrieveAllPilots(IObjectContainer db) 2 { 3 IObjectSet results = db.Get(typeof(Pilot)); 4 ListResult(results); 5 }

StructuredExample.vb: RetrieveAllPilots
1Public 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 ObjectCanDelete callback. See Callbacks chapter for more information.