Click here to Skip to main content
15,888,610 members
Articles / RavenDB
Tip/Trick

Embedded RavenDb in MVC 5

Rate me:
Please Sign up or sign in to vote.
4.28/5 (8 votes)
24 Nov 2014CPOL4 min read 34.1K   15   1
It’s basically a step-by-step to set up a working MVC project using RavenDb. Of course, it’s not meant to show any best practices nor any architecture design using RavenDb.

Introduction

If you have already read or used RavenDb in its embedded fashion, then this article is not for you. The main reason why I publish it is the multiple problems I faced with Nuget and RavenDb client that I want to share with you. I would also like to share the way in which I fixed them.

It’s basically a step-by-step to set up a working MVC project using RavenDb. Of course, it’s not meant to show any best practices nor any architecture design using RavenDb.

The fact that RavenDb is a NoSql database makes it light and easy to use, just like MongoDb or Redis. I already wrote a How-Tos about them. You could check them out here:

So let’s start with RavenDb:

  • Open Visual Studio 2013 and add an MVC 5 project.
  • Open the nuget manager console and type Install-Package RavenDB.Embedded to install embeddable client. In some Nuget Version, you may have a problem doing it like that.

I had the following error:

Updating 'System.Spatial 5.2.0' to 'System.Spatial 5.0.2' failed. Unable to find a version of 'RavenDB.Database' that is compatible with 'System.Spatial 5.0.2'.

Seems like trying to update the system.special package in reverse: from System.Spatial 5.2.0 to System.Spatial 5.0.2. To solve this Nuget problem, force Nuget to run on the highest version. So retype the previous install command as follows:

Install-Package RavenDB.Embedded -DependencyVersion Highest
using Raven.Client;
public class RavenDbConfig
{
    private static IDocumentStore _store;
    public static IDocumentStore Store
    {
        get
        {
            if (_store == null)
                throw new InvalidOperationException(
                "IDocumentStore has not been initialized.");
            return _store;
        }
    }

    public static IDocumentStore Initialize()
    {
        _store = new EmbeddableDocumentStore 
        { 
            ConnectionStringName = "RavenDB" 
        };
        _store.Conventions.IdentityPartsSeparator = "-";
        _store.Initialize();
        IndexCreation.CreateIndexes(Assembly.GetCallingAssembly(), Store);
        return _store;
    }
}

I will not go through every single line here (the previous snippet comes from Ayende’s sample on RavenDb web site) but basically, it initializes the EmbeddableDocumentStore based on your connection string. This object will give you access to the document store. The connection string as always located in webconfig file:

XML
<add name="RavenDB" connectionString="DataDir = ~\App_Data\Database" />

It’s maybe hard to see it at first glance, but at this point you have everything you need to start coding Ravendb stuff. But, you may run against a couple of problems regarding your compilation according to the versions you have installed for some DLL. Let's see the problems I met and how I resolved them:

  1. The first error was the newtonsoft.json. It was like:
    Could not load file or assembly 'Newtonsoft.Json, Version=4.5.0.0,
        Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies

    To resolve it, I run these commands in the Package Manager Console:

    uninstall-package newtonsoft.json -force
        install-package newtonsoft.json -version 4.5.11

    It seems brutal but it did the trick.

  2. Another error I run at was:

    The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code

    To fix it, I added the following in the Global.asax:

    C#
    GlobalConfiguration.Configuration.EnsureInitialized();

At this point, I think we resolved all possible problems that may occur in the project compilation. So let's move on the next step:

Add a base controller:

C#
public class M2aBaseController : Controller 
{
    public IDocumentSession DocumentSession { get; set; }

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.IsChildAction)
            return;
        this.DocumentSession = RavenDbConfig.Store.OpenSession();
        base.OnActionExecuting(filterContext);
    }

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.IsChildAction)
            return;
        if (this.DocumentSession != null && filterContext.Exception == null)
            this.DocumentSession.SaveChanges();
            this.DocumentSession.Dispose();
            base.OnActionExecuted(filterContext);
    }
}

Basically, the previous M2aBaseController will take care of the DocumentSession and make sure it’s open before any controller action that inherits the base Controller and disposed right after. It was suggested by Ayende, the co-founder of RavenDb, on the RavenDb web site.

This is just great for simple applications, but when it comes to heavy stuff applications, I would move all the code in M2aBaseController down to Data layer where it belongs. M2aBaseController will be the base repository in Repository Pattern scenario.

Besides the design of your application and in which layer you choose to handle what, the value of using RavenDb remains the same: simple to use, reliable and the client that comes with is the one who’s doing the magic behind the scenes.

To add an object to the data store and get back the data from it, your controller should inherit from the M2aBaseController. Then to create a document, add a create action method as follows:

C#
[HttpPost]        
public ActionResult Create()
{
    var schedule = new Schedule
    {
        Name=" Tirezzaf",
        Description = "Ad asegh ar tmurt iyi d-jjan imezwura",
        Departure= DateTime.Today.AddDays(2)
    };
    this.DocumentSession.Store(schedule);

    return RedirectToAction("Index");
}

Schedule is a business object and all what I need to do to save it is this.DocumentSession.Store(schedule);

And my Schedule is now in the data store (in database as relational databases folks would argue). It’s just so easy.

To get back the documents and send them to a view for display, add to your Index method (or another one):

C#
 var schedules = this.DocumentSession.Query<Schedule>().OrderByDescending
(i => i.Name).ToList();

As you noticed, it's just a regular Linq stuff to order or search for specific document. I think you get the idea, so you can just play with it a little bit to get used to it.

Of course, there is a lot of stuff you can discover about RavenDb, as indexes, sharding and how to manage your store via a browser, etc. The server version is also worth a try. A lot of information, how-tos and other documentation are available on RavenDb web site. Ayende answers questions out there.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) http://www.m2a.ca
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Sampath Lokuge22-Dec-16 22:44
Sampath Lokuge22-Dec-16 22:44 
Good one.Thanks Smile | :)

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.