Here's a collection of native query examples. These queries assume that there's a Pilot class with a name and age and a Car class with a pilot and name.
Note that for .NET 3.5 or newer we recommend to use LINQ instead of native queries.
This query shows you how compare a property for equality. In this example we compare the name of a person.
IList<Pilot> result = container.Query( delegate(Pilot pilot) { return pilot.Name == "John"; });
Dim result As IList(Of Pilot) = container.Query(Of Pilot)(AddressOf QueryJohns)
Private Shared Function QueryJohns(ByVal pilot As Pilot) Return pilot.Name = "John" End Function
You can compare values with the usual comparison operators.
IList<Pilot> result = container.Query( delegate(Pilot pilot) { return pilot.Age < 18; });
Dim result As IList(Of Pilot) = container.Query(Of Pilot)(AddressOf QueryAdults)
Private Shared Function QueryAdults(ByVal pilot As Pilot) Return pilot.Age < 18 End Function
Of course you can combine different comparisons. For example you can combine the greater and smaller than operators to check for a range of values.
IList<Pilot> result = container.Query( delegate(Pilot pilot) { return pilot.Age > 18 && pilot.Age < 30; });
Dim result As IList(Of Pilot) = container.Query(Of Pilot)(AddressOf QueryRange)
Private Shared Function QueryRange(ByVal pilot As Pilot) Return pilot.Age > 18 AndAlso pilot.Age < 30 End Function
Of course you can combine a arbitrary set of conditions with logical operators.
IList<Pilot> result = container.Query( delegate(Pilot pilot) { return (pilot.Age > 18 && pilot.Age < 30) || pilot.Name == "John"; });
Dim result As IList(Of Pilot) = container.Query(Of Pilot)(AddressOf CombineCriterias)
Private Shared Function CombineCriterias(ByVal pilot As Pilot) Return (pilot.Age > 18 AndAlso pilot.Age < 30) OrElse pilot.Name = "John" End Function
You can implement your query in a separate method and then just us it where you need it. This is especially useful when you reuse the same query multiple times. Or you want to give your query a clear name for documentation purposes.
First write your method:
private static bool AllJohns(Pilot pilot) { return pilot.Name == "John"; }
Private Shared Function AllJohns(ByVal pilot As Pilot) As Boolean Return pilot.Name = "John" End Function
And then use it:
IList<Pilot> result = container.Query(new Predicate<Pilot>(AllJohns));
Dim result As IList(Of Pilot) = container.Query(Of Pilot)(AddressOf AllJohns)
In principal your query can contain any code and can do the most complex comparisons. However in practice the are limitations. The simple queries are optimized and translated to SODA-queries. This is not possible for complex queries. If the query cannot be optimized, db4o will instantiate all objects and pass it to your query-object. This is a order of magnitude slower than a optimized native query and only feasible for smaller data sets.
IList<int> allowedAges = Array.AsReadOnly(new int[] {18, 20, 35}); IList<Pilot> result = container.Query( delegate(Pilot pilot) { return allowedAges.Contains(pilot.Age) || pilot.Name.ToLowerInvariant() == "John"; });
Dim result As IList(Of Pilot) = container.Query(Of Pilot)(AddressOf QueryWithAnyCode)
Private Shared Function QueryWithAnyCode(ByVal pilot As Pilot) Dim allowedAges As IList(Of Integer) = Array.AsReadOnly(New Integer() {18, 20, 35}) Return allowedAges.Contains(Pilot.Age) _ OrElse Pilot.Name.ToLowerInvariant() = "John" End Function