Over the last couple of days I’ve been playing with RavenDb. So far it’s been a very nice experience. I love the way POCO objects get persisted as complete graphs. You can have nicely encapsulated models too, with private setters, and the client API is a joy to use.
I’m putting together a little project as an excuse to play with Raven, MVC3 and NuPack. I’ll put it up on github soon, but simply put it’s a virtual pocket money bank account for parents and their kids. The model has a concept of Parent and Child both of which inherit a User abstract base class. One of the first things I wanted to check was that the Raven can return a polymorphic collections of Users.
Here’s a test that shows that it can:
[Test] public void Should_be_able_to_treat_Parents_and_Children_Polymorphically() { using (var session = store.OpenSession()) { var mike = new Parent("Mike Hadlow", "mike@yahoo.com"); var leo = mike.CreateChild("Leo", "leohadlow", "xxx"); var yuna = mike.CreateChild("Yuna", "yunahadlow", "xxx"); var john = new Parent("John Robinson", "john@gmail.com"); var jim = john.CreateChild("Jim", "jimrobinson", "xxx"); session.Store(mike); session.Store(leo); session.Store(yuna); session.Store(john); session.Store(jim); session.SaveChanges(); } using (var session = store.OpenSession()) { var users = session.LuceneQuery<User>().WaitForNonStaleResults().ToArray(); users.Length.ShouldEqual(5); users[0].Id.ShouldEqual("users/mike@yahoo.com"); users[1].Id.ShouldEqual("users/leohadlow"); users[2].Id.ShouldEqual("users/yunahadlow"); users[3].Id.ShouldEqual("users/john@gmail.com"); users[4].Id.ShouldEqual("users/jimrobinson"); users[0].GetType().Name.ShouldEqual("Parent"); users[1].GetType().Name.ShouldEqual("Child"); users[2].GetType().Name.ShouldEqual("Child"); users[3].GetType().Name.ShouldEqual("Parent"); users[4].GetType().Name.ShouldEqual("Child"); } }
For this to work, you have to configure Raven to understand that the type ‘User’ is represented by documents with ids that look like ‘users/xxx’:
var documentStore = new DocumentStore { Configuration = new RavenConfiguration { DataDirectory = path, RunInUnreliableYetFastModeThatIsNotSuitableForProduction = true }, Conventions = { FindTypeTagName = type => typeof(User).IsAssignableFrom(type) ? "users" : null } };
Other than that it just works.
Here’s my User class:
public abstract class User { public string Id { get; private set; } public string Name { get; private set; } public string UserName { get; private set; } protected User(string name, string userName) { Id = string.Format("users/{0}", userName); Name = name; UserName = userName; } }
Note the way that the User.Id gets created in the form ‘users/userName’.
No comments:
Post a Comment