Home > RavenDB > RavenDB Inheritance

RavenDB Inheritance

December 10th, 2011 Leave a comment Go to comments

Edit: Updated solution: http://www.philliphaydon.com/2011/12/ravendb-inheritance-revisited/

Continuing my learning of RavenDB, I wanted to see how it handled Inheritance.

I found: http://ravendb.net/faq/polymorphic-indexes

Which showed what to do allow you to select over all types of ‘Animal’ for the example shown. So I wanted to see what happens before and after using this method.

So like the example shown I’ve created an Animal, with a Dog and Cat.

public abstract class Animal
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Dog : Animal { }
public class Cat : Animal { }

Now if I insert a Dog and Cat:

using (var session = documentStore.OpenSession())
{
    session.Store(new Dog() { Name = "Test Dog" });
    session.Store(new Cat() { Name = "Test Cat" });

    session.SaveChanges();
}

What’s stored in RavenDB is two separate documents, one for ‘dogs’ and one for ‘cats’.

image

If I include the Convention.

var documentConvention =
    new DocumentConvention()
        {
            FindTypeTagName =
                type =>
                    {
                        if (typeof (Animal).IsAssignableFrom(type))
                            return "animals";
                        return DocumentConvention.DefaultTypeTagName(type);
                    }
        };

Note: You can do the conversion when the DocumentStore is initialized, I broke the two up so that it would fit easier into my blog. Otherwise it’s too nested and yucky.

var documentStore =
    (new DocumentStore()
            {
                Url = "http://localhost:8080",
                Conventions = documentConvention
            }).Initialize();

Now when I insert a Dog and Cat I get:

image

Awesome. If we look at the document however:

image

There is no information about it being a cat or dog, I thought it would add some sort of discriminator similar to how NHibernate works.

However, if we look at the Metadata tab:

image

We can see the CLR type is stored in the metadata so RavenDB knows what type to create when we query it.

This means if we query for ‘Animal’ we get a list of Dogs and Cats.

using (var session = documentStore.OpenSession())
{
    var result = session.Query<Animal>();

    foreach (var animal in result)
    {
        Console.WriteLine(animal.Name);
    }
}

 

image

However, if you wanted to query for just Dogs, like so:

var result = session.Query<Dog>().ToList();

It doesn’t seem to work Sad smile

image

I’m probably just doing something wrong, either way, the more I play with RavenDB. The more I love it.

Categories: RavenDB Tags:
  1. December 11th, 2011 at 21:27 | #1

    It is expected, you said that dogs are animals, and from the point of view of the database, it doesn”t distinguish between the two.
    Raven-Clr-Type is only ever used on the client, never for filtering on the server.

    You _can_ create an index that would do this sort of filtering, but that is something that you have to do explicitly, RavenDB will not do it for you

  1. No trackbacks yet.