Using Evaluations

For a simple example, let's take a Car class keeping a history of SensorReadout instances in a List member. Now imagine that we wanted to retrieve all cars that have assembled an even number of history entries. A quite contrived and seemingly trivial example, however, it gets us into trouble: Collections are transparent to the query API, it just 'looks through' them at their respective members.

So how can we get this done? Let's implement an Evaluation that expects the objects passed in to be instances of type Car and checks their history size.

EvenHistoryEvaluation.cs
01/* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com */ 02using Db4objects.Db4o.Query; 03 04namespace Db4objects.Db4odoc.Evaluations 05{ 06 public class EvenHistoryEvaluation : IEvaluation 07 { 08 public void Evaluate(ICandidate candidate) 09 { 10 Car car=(Car)candidate.GetObject(); 11 candidate.Include(car.History.Count % 2 == 0); 12 } 13 } 14}
EvenHistoryEvaluation.vb
01' Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com 02Imports Db4objects.Db4o.Query 03 04Namespace Db4objects.Db4odoc.Evaluations 05 Public Class EvenHistoryEvaluation 06 Implements IEvaluation 07 Public Sub Evaluate(ByVal candidate As ICandidate) Implements IEvaluation.Evaluate 08 Dim car As Car = DirectCast(candidate.GetObject(), Car) 09 candidate.Include(car.History.Count Mod 2 = 0) 10 End Sub 11 12 End Class 13End Namespace

To test it, let's add two cars with history sizes of one and two respectively:

EvaluationExample.cs: StoreCars
01private static void StoreCars(IObjectContainer db) 02 { 03 Pilot pilot1 = new Pilot("Michael Schumacher", 100); 04 Car car1 = new Car("Ferrari"); 05 car1.Pilot = pilot1; 06 car1.Snapshot(); 07 db.Set(car1); 08 Pilot pilot2 = new Pilot("Rubens Barrichello", 99); 09 Car car2 = new Car("BMW"); 10 car2.Pilot = pilot2; 11 car2.Snapshot(); 12 car2.Snapshot(); 13 db.Set(car2); 14 }
EvaluationExample.vb: StoreCars
01Private Shared Sub StoreCars(ByVal db As IObjectContainer) 02 Dim pilot1 As Pilot = New Pilot("Michael Schumacher", 100) 03 Dim car1 As Car = New Car("Ferrari") 04 car1.Pilot = pilot1 05 car1.Snapshot() 06 db.Set(car1) 07 Dim pilot2 As Pilot = New Pilot("Rubens Barrichello", 99) 08 Dim car2 As Car = New Car("BMW") 09 car2.Pilot = pilot2 10 car2.Snapshot() 11 car2.Snapshot() 12 db.Set(car2) 13 End Sub

and run our evaluation against them:

EvaluationExample.cs: QueryWithEvaluation
1private static void QueryWithEvaluation(IObjectContainer db) 2 { 3 IQuery query = db.Query(); 4 query.Constrain(typeof (Car)); 5 query.Constrain(new EvenHistoryEvaluation()); 6 IObjectSet result = query.Execute(); 7 ListResult(result); 8 }
EvaluationExample.vb: QueryWithEvaluation
1Private Shared Sub QueryWithEvaluation(ByVal db As IObjectContainer) 2 Dim query As IQuery = db.Query() 3 query.Constrain(GetType(Car)) 4 query.Constrain(New EvenHistoryEvaluation()) 5 Dim result As IObjectSet = query.Execute() 6 ListResult(result) 7 End Sub