Referential Integrity

Db4o does not have a built-in referential integrity checking mechanism. Luckily EventRegistry gives you access to all the necessary events to implement it. You will just need to trigger validation on create, update or delete and cancel the action if the integrity is going to be broken.

For example, if Car object is referencing Pilot and the referenced object should exist, this can be ensured with the following handler in deleting() event:

CallbacksExample.cs: TestIntegrityCheck
01private static void TestIntegrityCheck() 02 { 03 FillContainer(); 04 IObjectContainer container = Db4oFactory.OpenFile(Db4oFileName); 05 try { 06 IEventRegistry registry = EventRegistryFactory.ForObjectContainer(container); 07 // register an event handler, which will stop Deleting a pilot when it is referenced from a car 08 registry.Deleting += new CancellableObjectEventHandler(OnDeleting); 09 10 // check the contents of the database 11 IObjectSet result = container.Get(null); 12 ListResult(result); 13 14 // try to delete all the pilots 15 result = container.Get(typeof(Pilot)); 16 while(result.HasNext()) { 17 container.Delete(result.Next()); 18 } 19 // check if any of the objects were Deleted 20 result = container.Get(null); 21 ListResult(result); 22 } finally { 23 CloseContainer(); 24 } 25 }
CallbacksExample.cs: OnDeleting
01private static void OnDeleting(object sender, CancellableObjectEventArgs args) 02 { 03 Object obj = args.Object; 04 if (obj is Pilot) 05 { 06 IObjectContainer container = OpenContainer(); 07 // search for the cars referencing the pilot object 08 IQuery q = container.Query(); 09 q.Constrain(typeof(Car)); 10 q.Descend("_pilot").Constrain(obj); 11 IObjectSet result = q.Execute(); 12 if (result.Size() > 0) 13 { 14 Console.WriteLine("Object " + (Pilot)obj + " can't be Deleted as object container has references to it"); 15 args.Cancel(); 16 } 17 } 18 }

CallbacksExample.vb: TestIntegrityCheck
01Private Shared Sub TestIntegrityCheck() 02 FillContainer() 03 Dim container As IObjectContainer = Db4oFactory.OpenFile(Db4oFileName) 04 Try 05 Dim registry As IEventRegistry = EventRegistryFactory.ForObjectContainer(container) 06 ' register an event handler, which will stop Deleting a pilot when it is referenced from a car 07 AddHandler registry.Deleting, AddressOf OnDeleting 08 ' check the contents of the database 09 Dim result As IObjectSet = container.Get(Nothing) 10 ListResult(result) 11 ' try to delete all the pilots 12 result = container.Get(GetType(Pilot)) 13 While result.HasNext 14 container.Delete(result.Next) 15 End While 16 ' check if any of the objects were Deleted 17 result = container.Get(Nothing) 18 ListResult(result) 19 Finally 20 CloseContainer() 21 End Try 22 End Sub
CallbacksExample.vb: OnDeleting
01Private Shared Sub OnDeleting(ByVal sender As Object, ByVal args As CancellableObjectEventArgs) 02 Dim obj As Object = args.Object 03 If TypeOf obj Is Pilot Then 04 ' search for the cars referencing the pilot object 05 Dim container As IObjectContainer = OpenContainer() 06 Dim q As IQuery = container.Query 07 q.Constrain(GetType(Car)) 08 q.Descend("_pilot").Constrain(obj) 09 Dim result As IObjectSet = q.Execute 10 If result.Size > 0 Then 11 Console.WriteLine("Object " + CType(obj, Pilot).ToString() + " can't be Deleted as object container has references to it") 12 args.Cancel() 13 End If 14 End If 15 End Sub

You can also add handlers for creating() and updating() events for a Car object to make sure that the pilot field is not null.