Look Mom, NoSQL! - 6. My First RavenDB Application (2)
In my previous post in this series on NoSQL Databases, I showed how RavenDB embedded could be added to an existing ASP.NET MVC 3 application using NuGet and how it can be configured to use a folder in the App_Data folder.
In this blog I will add the code needed for my TaskController class to use RavenDB to store its data.
Everything in RavenDB goes through an instance of IDocumentStore. There are two classes in the RavenDB API which implement this interface DocumentStore and EmbeddedDocumentStore. We will be using the latter.
We can create a RavenDocumentStore class which is like the DataContext or DbContext classes in Entity Framework.
Listing 1: The RavenDocumentStore Class |
public class RavenDocumentStore { private static IDocumentStore instance; public static IDocumentStore Instance { get { if (instance == null) throw new InvalidOperationException("…"); return instance; } } public static IDocumentStore Initialize() { instance = new EmbeddableDocumentStore { ConnectionStringName = "RavenDB" }; instance.Conventions.IdentityPartsSeparator = "-"; instance.Initialize(); return instance; } } |
The static property Instance ensures that we only have one instance of the DocumentStore, and the Initialize method can be called in Application_Start. We could have created the instance inside the Instance getter, but that would not be thread-safe.
Listing 2: The Application Start method |
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RavenDocumentStore.Initialize(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); } |
We are going to need an IDocumentSession to do the work. We could create a new IDocumentSession instance at the beginning of each Action method and then dispose of it at the end of each method. But MVC has two very convenient hooks to do this – OnActionExecuting and OnActionExecuted. These methods are executed before and after each action method, so we will create a new IDocumentSession in OnActionExecuting and dispose of it in OnActionExecuted. To do this we will create a BaseRavenController class to act as a base class for our TaskController (Listing 3).
Listing 3: The BasenRavenController class |
public class BaseRavenController : Controller { public IDocumentSession RavenSession { get; set; } protected override void OnActionExecuting(ActionExecutingContext filterContext) { RavenSession = RavenDocumentStore.Instance.OpenSession(); base.OnActionExecuting(filterContext); } protected override void OnActionExecuted(ActionExecutedContext filterContext) { if (RavenSession != null) { RavenSession.SaveChanges(); RavenSession.Dispose(); } base.OnActionExecuted(filterContext); } } |
Finally we can then modify each action method to use the RavenSession instead of the Entity Framework DbContext. As an example the Index action (Listing 4) and the Edit actions (Listing 5) are shown.
Listing 4: The Index Action method |
public ViewResult Index() { var tasks = RavenSession.Query |
Listing 5: The Edit Action methods |
public ActionResult Edit(string id) { Task task = RavenSession.Load |
That is basically it – although there is one last change that needs to be made. RavenDB uses a “key” to identify each document. By default, just like an Identity column in SQL Server, RavenDB will generate this key automatically – the default behaviour being to create a key of the form “tasks/1” – i.e. the plural of the object’s name followed by the default “/” separator and a hilo generated integer.
The default separator can be changed and we did that in Listing 1 by setting the IdentityPartsSeparator to a “-“, so that we didn’t interfere with the Url separator in our routes. And since we now have a string “key” the Id property of our Task object (and all the Action method parameters) can be changed to a string.
Figure 1 and Figure 2 show the Tasks Application running in List and Edit mode.
Figure 1: The MyTasks MVC Application in List (Index) view |
![]() |
Figure 2: The MyTasks MVC Application in Edit view |
![]() |
So that’s it – its not very hard at all to start working with RavenDB. The only challenge so far being that I cannot look into the Data Store in the same way that I can with the SQL Server tools in Visual Studio or SQL Management Studio.
However, this is not the end of this series of Blogs. I will continue to explore NoSQL databases, in particular RavenDB.