The Problem Solver

Tell me and I will forget
Show me and I will remember
Involve me and I will understand
- Confucius -

Google Ads

This Blog

Syndication

Search

Tags

News





  • View Maurice De Beijer's profile on LinkedIn

Community

Email Notifications

Explore

Archives

November 2012 - Posts

In my previous two posts about RavenDB I used a Book class as the example. The first example was an ASP.NET MVC 3 application and the second was an ASP.NET MVC 4 application and I just copies the Books class from the first to the second example. As I just used the default namespace in both projects .NET would consider this two different classes, after all the namespace and assemblies are different.

 

How does RavenDB handle CLR types

It turns out RavenDB doesn’t really care about these differences with namespaces and assemblies. The extra information is stored as metadata along with the book data but only the actual class name, Book in this case, is used as the type discriminator. The screenshot below shows the metadata of one of the books I created using the original MVC3 application.

image

However when I started the second MVC4 application all 5 of the previously created books just appeared, even though the Book class in that application used a different namespace. And I could edit and save them without any problems. This did change the metadata to display the new namespace as shown in the screenshot below.

image

 

The important thing to remember here is that RavenDB just cares about our class name and will just use the data. In this case not much of a problem but that will not always be the case.

 

Using multiple database

The solution is the same as with SQL Server, just create multiple database to separate data from different application. Now you can go into the RavenDB management studio and create a new database there.

image

That works just fine But you can do it even easier. Just specify the database name in the connection string. In that case RavenDB automatically used that database for all operations and if it doesn’t exist yet it will be created as needed.

   1: <connectionStrings>
   2:   <add name="ravenDB"
   3:        connectionString="Url=http://localhost:8080;Database=Mvc4Demo"/>
   4: </connectionStrings>
 
Using unique databases for your applications you can be certain that you don’t inadvertently start mixing data from different applications just because the class name is the same.
 

Deleting old databases

One none obvious thing is how to delete old databases you don’t need any longer. There is no delete database option or command in RavenDB. In the screenshot below I have a database called OldData.
image
In order to delete it I have to go the default database and find the document pointing to this database and delete this.
image

Once that is done I can locate the actual folder on disk and delete it.

image

 

Enjoy!

Posted by Maurice | with no comments
Filed under: , ,

Some people might have wondered why I used ASP.NET MVC 3 in my previous blog post. The reason is that the RavenDB.Client package uses Newtonsoft.Json and ASP.NET MVC 4 also has a dependency on Newtonsoft.Json. In itself this isn’t a problem except that RavenDB requires Newtonsoft.Json version 4.0.8 and ASP.NET MVC 4 ships with a much newer version of Newtonsoft.Json, to be exact version 4.5.6.

The result is that trying to Install-Package RavenDB.Client produces the following error:

Install-Package : Updating 'Newtonsoft.Json 4.5.6' to 'Newtonsoft.Json 4.0.8' failed. Unable to find a version of 'Microsoft.AspNet.
WebApi.Client' that is compatible with 'Newtonsoft.Json 4.0.8'.

 

Does that mean you can’t use RavenDB with ASP.NET MCV 4?

No fortunately you can still go ahead and user RavenDB.Client. Instead of the default package you need to installl a specific version which is build with the same version of Newtonsoft.Json as ASP.NET MVC4.

   1: Install-Package RavenDB.Client -Version 1.0.971

 

After including this package, and copying the code from the previous post. We can run the ASP.NET MCV 4 application and we get to see the same books as before except now with the new stying.

image

 

However one thing to keep in mind is that RavenDB.Client is the only RavenDB NuGet package build against this version of Newtonsoft.Json. There is no updated version of RavenDB.Server or any of the other packages and that includes RavenDB.Embedded which can be very useful if you want to embed RavenDB server and client into one application. See this blog post by Ayende Rahien for more details on this NuGet package.

 

Enjoy!

Posted by Maurice | with no comments

RavenDB is one of the newer document type databases that is conceptually comparable to MongoDB or CouchDB. One of the nice thing about RavenDB, at least for a .NET developer, is that is has been developed with .NET in mind from the start. And this makes it really easy to get started with. In fact it is so easy to get started with that it surprises me that not everyone is using it.

 

One of the things that attract me to document databases like RavenDB is the fact that they are really fast and schema free. This means that I don’t have to worry about creating database tables or those administrator like tasks. Instead I just create my C# classes and store them as documents in the database. Make a change to my class, no problem it just keeps on working.

 

Creating a real simple ASP.NET MVC application using RavenDB

A quick demo will show just how easy it is to get started. I am starting with a standard ASP.NET MVC 3 application here. In order to get the RavenDB client and server packages I use NuGet to install them using the following two commands in the NuGet Package Manager Console:

   1: Install-Package RavenDB.Client
   2: Install-Package RavenDB.Server

 

The RavenDB Server

The RavenDB.Server package installs the server bit. There are other ways of doing things but for now lets do the simplest and just navigate to the Raven.Server.Exe and start it.

image

This will start the server running and by default it will listen on for HTTP traffic on port 8080. The server console will display all command that execute helping with debugging potential issues.

image

 

The RavenDB Client

The RavenDB.Client NuGet package installed the normal way into our project and added some references to the RavenDB client libraries. In order to use RavenDB in our C# code we first need to create a DocumentStore object. This is an object that only needs to be created once and can be cached for the duration of the application live time. One nice and simple way of doing this is by adding the following bit of code to the Global.asax and calling this from the Application_Start() function.

 

   1: public static IDocumentStore RavenDBDocumentStore { get; private set; }
   2:  
   3: private static void CreateRavenDBDocumentStore()
   4: {
   5:     RavenDBDocumentStore = new DocumentStore
   6:     {
   7:         ConnectionStringName = "ravenDB"
   8:     }.Initialize();
   9: }

In this case I am pointing to a connection string in the web.config so lets make sure that is added. Basically I am pointing this to HTTP port 8080 on the local machine which is the server we started before this.

   1: <connectionStrings>
   2:   <add name="DefaultConnection"
   3:        providerName="System.Data.SqlClient"
   4:        connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-RavenMvc-20121125145005;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-RavenMvc-20121125145005.mdf" />
   5:   <add name="ravenDB"
   6:        connectionString="Url=http://localhost:8080"/>
   7: </connectionStrings>

 

In order to store or retrieve data we need to use the DocumentStore to open a session. Most database interactions, and all standard ones, are done through a session object. This session object should be short lived, create one, do a few interactions with it and dispose of it. And when it comes to a few interactions RavenDB pushes you towards the right thing. Do to many database queries and you will see an InvalidOperationException with message “The maximum number of requests (30) allowed for this session has been reached.” informing you that you can do only 30 actions at the time. This might seems strange but RavenDB has a number of these defaults that lead developers towards making the right choices.

In this demo I am going to use a simple book application to show how simple it is to get started with RavenDB. The book class is pretty basic and looks like this;

   1: namespace RavenMvc.Models
   2: {
   3:     public class Book
   4:     {
   5:         public int Id { get; set; }
   6:         public string Title { get; set; }
   7:         public string Author { get; set; }
   8:     }
   9: }

 

A list of books application

Showing a lost of books is real simple. All I need is the following code:

   1: public class BooksController : Controller
   2: {
   3:     //
   4:     // GET: /Books/
   5:     public ActionResult Index()
   6:     {
   7:         using (var session = MvcApplication.RavenDBDocumentStore.OpenSession())
   8:         {
   9:             var books = session.Query<Book>().ToList();
  10:             return View(books);
  11:         }
  12:     }
  13: }

Just running this will work just fine. Note that I have not created any databases or tables. Instead RavenDB will just check to see of it knows about books and if so return them. In fact it will return the first 128 by default as that is another of those default to help developers make the right choice. The thing to note in the code is that I am using the DocumentStore to create a new session object, using the session to do a query and then disposing the session object again. This is the basic approach when using RavenDB that you keep on repeating.

image

Loading a single book

The session.Query<Book> returns an IQueryable object so you could just start do queries. However if you know the identity of the book it is faster to use the Load() function instead.

   1: //
   2: // GET: /Books/Details/5
   3: public ActionResult Details(int id)
   4: {
   5:     using (var session = MvcApplication.RavenDBDocumentStore.OpenSession())
   6:     {
   7:         var book = session.Load<Book>(id);
   8:         return View(book);
   9:     }
  10: }

 

Storing a new book in the database

Adding  a new book isn’t much harder. In this case we do need to make sure we call SaveChanges() on the session as that commits the changes to the database. If we don’t do this they will be lost when the session is disposed.

   1: //
   2:         // POST: /Books/Create
   3:         [HttpPost]
   4:         public ActionResult Create(Book book)
   5:         {
   6:             if (ModelState.IsValid)
   7:             {
   8:                 using (var session = MvcApplication.RavenDBDocumentStore.OpenSession())
   9:                 {
  10:                     session.Store(book);
  11:                     session.SaveChanges();
  12:                 }
  13:  
  14:                 return RedirectToAction("Index");
  15:             }
  16:  
  17:             return View(book);
  18:         }

The important thing to remember is we haven’t defined any schema in the database for this to work. Instead RavenDB just saves the object. In fact it converts it to a JSON format first and stores it that way. The data is easy to see. Part of the RavenDB.Server package is a Silverlight client that lets you manage the server and inspect, or even change, the data. After adding a few books this looks like this:

image

If we edit a document we can see the actual JSON representation of the book. Note that the associated metadata contains the CLR type so RavenDB knows how to handle your query and deserialize the data.

image

 

Updating and deleting the books is just as simple.

   1: //
   2: // POST: /Books/Edit/5
   3: [HttpPost]
   4: public ActionResult Edit(int id, Book updated)
   5: {
   6:     if (ModelState.IsValid)
   7:     {
   8:         using (var session = MvcApplication.RavenDBDocumentStore.OpenSession())
   9:         {
  10:             var book = session.Load<Book>(id);
  11:             book.Title = updated.Title;
  12:             book.Author = updated.Author;
  13:             session.Store(book);
  14:             session.SaveChanges();
  15:         }
  16:  
  17:         return RedirectToAction("Index");
  18:     }
  19:  
  20:     return View(updated);
  21: }
  22:  
  23: //
  24: // POST: /Books/Delete/5
  25: [HttpPost]
  26: public ActionResult Delete(int id, Book deleted)
  27: {
  28:     using (var session = MvcApplication.RavenDBDocumentStore.OpenSession())
  29:     {
  30:         var book = session.Load<Book>(id);
  31:         session.Delete(book);
  32:         session.SaveChanges();
  33:     }
  34:  
  35:     return RedirectToAction("Index");
  36: }

 

That is all there is to it to get started. With a bit of simple C# code I can store books and I never needed to worry about the database side of things. Sweet :-)

 

Enjoy!

The standard workflow with web development is run the web application, make some changes to your CSS in Visual Studio, flip back to the browser and reload the page to see the effect. While this works relatively well it can be somewhat slow at times.

 

One improvement is make changes to your CSS in the browser. I use Google Chrome as my main browser and it’s CSS and JavaScript viewer is actually an editor so you can make changes there. The nice thing is you see the effect of your changes immediately making for a much faster feedback loop. The drawback is that changes are made in memory and you have to copy them back to the original CSS/JavaScript file. And if you accidently navigate away or reload the page your changes are gone.

 

Tincr to the rescue

Sometimes a utility comes along that is so incredibly useful that you wonder how you managed to live without is. Tincr is one of those plugins for Chrome that makes you wonder how you could do web development without it.

The basic idea behind Tincr is to create a link between the CSS/JavaScript files on disk in your project and in the browser and keep them in sync. That means that you can make any change you want to your CSS file in Visual Studio and as soon as you hit save the browser is automatically updated. The same goes the other way, make a change to your CSS in the Chrome developer tools and the change will be save to disk automatically.

 

How cool is that?

 

Here is a short demo from the maker showing Tincr in action.

Using Tincr with an ASP.NET MVC application is easy.

After installing Tincr you will see an additional tab in the Chrome developer tools. Select this and set the project type to HTTP Web Server and select the root directory for the project. By default auto refresh and auto save are enabled allowing for 2 way syncing.

image

Make sure to keep the Chrome Developer Tools open and switch back to Visual Studio and make some changes to your CSS. As soon as you save the file you will see the browser window update.

 

One gotcha with Windows 8

Unfortunately this plugin won’t install on Google Chrome running on Windows 8 even though other plugins work just fine. I am not 100% sure why but believe this is because it uses the NPAPI Chrome File API to get access to the file system.

 

Update: Lauricio Su came up with a good workaround. See here for more details.

 

Recommended!

 

Now if we would only have a similar plugin for Internet Explorer Winking smile

Posted by Maurice | with no comments

The PowerPoint and samples from my presentation at the QNH DevDays in Arnhem.

 

SignalR demo

Other demos

 

Enjoy!

Posted by Maurice | with no comments

In deze podcast spreekt Maurice de Beijer met Peter Paul Koch over zijn werk bij de Fronteers organisatie, zijn ruime ervaring met mobiel web ontwikkeling en de recente poll die hij gedaan heeft over het gebruik van JavaScript libraries.

Links:

Met dank aan onze sponsor RedGate.

Posted by Maurice | with no comments
Filed under: ,