Easily connect to RavenDB data via C#


Working with the .NET client API

The easiest way to interface with a RavenDB document store is through the .NET client API. The API is accessed via the Raven.Client.Lightweight-3.5.dll file, which can be found in the Client-3.5 directory of your RavenDB installation. (The version number — 3.5 in this case — may change with future RavenDB releases.) If you’re using Visual Studio, you add a reference to this DLL in your project. Once this reference is added, a using statement can be used to add a reference within the code (e.g., using Raven.Client).
With the reference added, there are two steps to working with the document store:
  1. Connect to the document store: You connect to your RavenDB document store instance. It is recommended that one document store instance is created per application.
  2. Create a session: You establish a session via the document store. You should create a session instance each time you have to interact with the document store.
Once the document store and session objects are instantiated, you may interact with your RavenDB installation; this may include adding documents, updating documents, querying the data store, and so forth. The following code snippet instantiates the document store and session objects using my local RavenDB installation.
var documentStore = new Raven.Client.Document.DocumentStore { Url = "http://localhost:8080" };
documentStore.Initialize();
using(var session = documentStore.OpenSession())
{
// Work with document store
}
The code uses the complete object path to demonstrate where they are located within the namespace, but as previously mentioned, this can be shortened via the using keyword in the code header. The first line creates an instance of the DocumentStore class using the Web address of the RavenDB installation. The next line instantiates the DocumentStore object with the following line (using statement) creating a session via the DocumentStore. With the session created, you can easily interact with the RavenDB document store.

Working with documents

As we explored in my previous Software Engineer post, RavenDB is a document-centric data store. As an example, we will store website information in our RavenDB backend. The website URL will be stored along with a title and notes. The following C# class will map this to our document type.
public class Site
{
public string Title { get; set; }
public string URL { get; set; }
public string Notes { get; set; }
}
The code to add a document builds upon the earlier example where a session is created. The code takes it a bit further by adding a document (using the class) to the store. Once the session is established, an instance of the Site class is created and populated with the data to be stored. The session Store method stores the new document in the session. You can create multiple documents and store them until you’re ready to save the changes. The SaveChanges method puts the data in the RavenDB instance.
var documentStore = new Raven.Client.Document.DocumentStore { Url = "http://localhost:8080" };
documentStore.Initialize();
var site = new Site {
Title = "CNet TV",
URL = "http://cnettv.cnet.com",
Notes = "Tech shows"
};
using(var session = documentStore.OpenSession())    {
session.Store(site);
session.SaveChanges();
}
Figure A shows the document added to the data store via the RavenDB Web interface.
Figure A
Document added to RavenDB displayed in the Web interface (Click the image to enlarge.)
It is interesting to see what is added to the document metadata (see the Metadata tab in Figure A), as well as what the following listing shows; RavenDB uses the namespace of the application (RavenDB1) and the class name of the entity (Sites) to assign metadata properties.
{
"Raven-Entity-Name": "Sites",
"Raven-Clr-Type": "RavenDB1.Site, RavenDB1"
}
An interesting aspect of adding this document is how do you identify it after it is added? That is, in the relational world, there are key values on tables that serve many purposes with one assigning a unique identifying value to a row of data. While RavenDB isn’t relational, it does utilize key values to identify a document, and this can easily be incorporated into the code. The first step is adding a string Id property to our object. Once this is added, you do not populate it when a document is created, but RavenDB will populate it with an identifying value. The following console application demonstrates this approach.
namespace RavenDB1 {
public class Site  {
public string Id { get; set; }
public string Title { get; set; }
public string URL { get; set; }
public string Notes { get; set; }
}
class Program  {
static void Main(string[] args)  {
var documentStore = new Raven.Client.Document.DocumentStore { Url = "http://localhost:8080" };
documentStore.Initialize();
var site = new Site { Title = "CNet TV", URL = "http://cnettv.cnet.com", Notes = "Tech shows" };
using(var session = documentStore.OpenSession())  {
session.Store(site);
session.SaveChanges();
Console.WriteLine("ID: " + site.Id);
}  }  }  }
The final line displays the Id value of the newly created document (sites/193 in my case); this isn’t the only way to work with ID values — an overview is available online. While adding documents is useful, the real power in a data store is querying the data. The RavenDB platform utilizes the LINQsyntax, so once again it does not follow the traditional RDBMS world where SELECT statements are used. The following example builds upon the previous code to pull all documents from the data store that have a value of CNET as its title.
var documentStore = new Raven.Client.Document.DocumentStore { Url = "http://localhost:8080" };
documentStore.Initialize();
using(var session = documentStore.OpenSession())  {
var sites = session.Query<Site>()
.Where(x => x.Title == "CNet")
.ToList();
for (int i = 0; i < sites.Count; i++)   {
Console.WriteLine(sites[i].Title + " - " + sites[i].URL);
}  }
The session Query method is used to issue the LINQ command, which includes a Where to define what to select, and the ToList method converts the results to a GenericList object. Finally, a for loop is used to loop through the results, which are displayed in the console.

Starting point

As a developer who has worked with relational database systems for years, working with RavenDB has been a pleasant experience with some uneasiness as I wade through a less rigid system. The .NET client API included with a RavenDB installation makes it easy to get up and running with the document store in no time. The simple examples in this post build the groundwork for much more advanced integration.
Have you jumped on the NoSQL bandwagon, or does it make you uneasy? Are you currently using RavenDB or an alternative? Share your thoughts and experiences with the community.