Aug 10, 2009

Did you know ? (Part I) - Executing sub-queries

With this post I want to start a series of "Did you know?" regarding programing related topics and db4o features / usage patterns that may not be well known.

As the first one, take a look in the following code:
 
class Address
{
  public Address(string streetName)
  {
     StreetName = streetName;
  }

  public string StreetName { get; set; }

  public override string ToString()
  {
     return "Address: " + StreetName;
  }
}

class Person
{
   public Person(string name, Address address)
   {
       Name = name;
      _address = address;
   }

   public Address Address
   {
      get { return _address; }
      set { _address = value; }
   }

   public string Name { get; set;}

   public override string ToString()
   {
      return "Person: " + Name;
   }
   private Address _address;
}

using (var db = Db4oEmbedded.OpenFile(databaseFileName))
{
   db.Store(new Person("Adriano", new Address("You know where I live")));
   db.Store(new Person("Sulivan", new Address("Monstropolis")));
   db.Store(new Person("Mike", new Address("Who cares?")));
   db.Store(new Address("Foo address"));

   IQuery q =  db.Query();
   q.Constrain(typeof(Person));
   IQuery descendantQuery = q.Descend("_address");
   
   foreach(var result in descendantQuery.Execute())
   {
      Console.WriteLine(result);
   }
}

What do you think will be the result?

Well, it will return all addresses objects that have a Person as a parent, i.e, "foo address" will not be retrieved/shown! 

You can even specify constrains in both queries (getting the addresses for persons with a specific name!).

Note that this does not work for fields with value type semantics (basically any primitive value, enums [in .Net], string, etc.).

Do you have any db4o topic that, in your opinion, is commonly misunderstood and you would like to discuss? Please, let us know :)



Have fun!

Adriano