Thoughts from the Wet Coast

The musings of an ASP.NET Developer from Canada's We(s)t Coast

Look Mom, NoSQL! - 6. My First RavenDB Application (2)

Category: ASP.NET Data
Last Modified: May 2 2017
Nov 19 2011

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().ToList();     return View(tasks); }

 

Listing 5: The Edit Action methods

public ActionResult Edit(string id) {     Task task = RavenSession.Load(id);     return View(task); }  [HttpPost] public ActionResult Edit(Task task) {     if (ModelState.IsValid)     {         RavenSession.Store(task);         return RedirectToAction("Index");     }     return View(task); }

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

image_5

 

Figure 2: The MyTasks MVC Application in Edit view

image_6

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.

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

Categories

Tags