Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / database / NoSQL

An Abstract Generic DAO for RavenDB

4.82/5 (3 votes)
26 Feb 2016CPOL1 min read 9.4K  
Abstract and generic DAO for RavenDB

Introduction

In this article, I will be walking you with a code sample on how to build an Abstract DAO (Data Access Object) for Raven DB.

There are times you wish to perform CRUD operation on the RavenDB entities, in such cases, it would be a good idea to use a generic reusable objects to make our life ease in performing repetitive work. Yes, that’s exactly why we need to come-up with a helper class or an Abstract DAO to perform all sorts of the repetitive tasks.

If you are asking a question on what sorts of operations would you like to perform on the entities, here are the common operations that one would prefer to go.

  1. Get – Get document by ID.
  2. GetAll - Get all documents.
  3. GetPagedList – Get paged list of documents.
  4. GetDocumentStore – Get document store. In memory vs real database.
  5. Save – Persist document.
  6. Delete – Delete document.

Note – We use the document store to open a session on the default database so we can perform database operations on RavenDB.  

Background

Some understanding and work experience with NoSQL database.

Using the code

Here’s the code sample for building an Abstract DAO for RavenDB.

/// <summary>
/// Abstract DAO for RavenDB
/// </summary>
/// <typeparam name="T">T is an generic RavenDB Entity</typeparam>
public abstract class Dao<T>
{
    string _database = "";
    bool _inMemory = false;

    public Dao(string database, bool inMemory = false)
    {
        _database = database;
        _inMemory = inMemory;
    }

    public IDocumentStore GetDocumentStore()
    {
        if (_inMemory)
            return DocumentStoreHolder.GetInMemoryStore();

        return DocumentStoreHolder.GetStore();
    }

    public virtual T Get(string id)
    {
        using (var documentStore = GetDocumentStore())
        {
            using (var session = documentStore.OpenSession(_database))
            {
                return session.Load<T>(id);
            }
        }
    }

    public virtual List<T> GetAll()
    {
        using (var documentStore = GetDocumentStore())
        {
            using (var session = documentStore.OpenSession(_database))
            {
                return session.Query<T>().ToList();
            }
        }
    }

    public List<T> GetPagedList(int startingPageIndex, int pageSize)
    {
        using (var documentStore = GetDocumentStore())
        {
            using (IDocumentSession session = documentStore.OpenSession(_database))
            {
                return session.Query<T>()
                              .Take(pageSize)
                              .Skip(startingPageIndex * pageSize)
                              .ToList();
            }
        }
    }

    public virtual void Save(T entity)
    {
        using (var documentStore = GetDocumentStore())
        {
            using (var session = documentStore.OpenSession(_database))
            {
                session.Store(entity);
                session.SaveChanges(); // Save all pending changes to server
            }
        }
    }

    public virtual void Delete(string id)
    {
        using (var documentStore = GetDocumentStore())
        {
            using (var session = documentStore.OpenSession(_database))
            {
                T entity = session.Load<T>(id);
                session.Delete(entity);
                session.SaveChanges();
            }
        }
    }
}

The following code is just an example to show the usage of our Abstract DAO. We are building a “CompanyDao” by extending a generic DAO with the specific type i.e “Company”.

public class CompanyDao : Dao<Company>
{
       public CompanyDao(string database, bool inMemory = false) :
           base(database, inMemory)
       {
       }
}

Below is the code snippet for making a call to “CompanyDao”.

void SaveCompanyInfo()
{
            var company = new Company
            {
                ExternalId = "ALFKI",
                Name = "Alfreds Futterkiste",
                Contact = new Contact
                {
                    Name = "Maria Anders",
                    Title = "Sales Representative"
                },
                Address = new Address
                {
                    Line1 = "Obere Str. 57",
                    Line2 = "Zip 12345",
                    City = "Berlin",
                    Region = null,
                    PostalCode = 12209,
                    Country = "Germany"
                },
                Phone = "030-0074321",
                Fax = "030-0076545"
            };

            var companyDao = new CompanyDao(DATABASE, inMemory);
            companyDao.Save(company);
}

Points of Interest

There's always something new I am playing with technology :)

History

Version 1.0 - Published initial version of tip 02/26/2016.

License

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