RavenDB is a document database. The main difference between RavenDB and a relational database is, that RavenDB doesn’t support relation between the rows/entities/documents. A document contains structural data, which is stored in JSON format.
This is a quickstart into RavenDB:
Step 1 – Database:
Create a new database. This DB doesn’t contain any structure. It’s just a empty container.
Step 2 – Structure:
Define your entity/POCO/document structure in C#.
I created a company and a employee class. A company can contain multiple employees.
public class Company { public string Id { get; set; } public string Type { get { return "company"; } } public string Name { get; set; } public string Region { get; set; } public IListEmployees { get; set; } } public class Employee { public enum ERole { CEO, CFO, Developer } public string Id { get; set; } public string Type { get { return "employee"; } } public string Firstname { get; set; } public string Lastname { get; set; } public ERole Role { get; set; } }
Example -> Create new document:
Following code snippet creates a new document with one company and three employees.
using (var documentStore = new DocumentStore { Url = "http://myurl:8080/" }) { documentStore.Initialize(); using (var session = documentStore.OpenSession("testDB")) { var company = new Company() { Id = "company/1", Name = "Tvd" }; company.Employees = new List() { new Employee() { Id = "emp/1", Firstname = "Darko", Lastname = "Micic", Role = Employee.ERole.Developer }, new Employee() { Id = "emp/2", Firstname = "Steve", Lastname = "Steven", Role = Employee.ERole.Developer }, new Employee() { Id = "emp/3", Firstname = "Max", Lastname = "Min", Role = Employee.ERole.CFO }, }; session.Store(company); session.SaveChanges(); }
The stored document is structured as shown here:
{ "Type": "company", "Name": "Tvd", "Region": null, "Employees": [ { "Id": "emp/1", "Type": "employee", "Firstname": "Darko", "Lastname": "Micic", "Role": "Developer" }, { "Id": "emp/2", "Type": "employee", "Firstname": "Steve", "Lastname": "Steven", "Role": "Developer" }, { "Id": "emp/3", "Type": "employee", "Firstname": "Max", "Lastname": "Min", "Role": "CFO" } ] }
Example -> Read document:
Reading documents is quiet easy. Open a new session and run a query. (LINQ or with Lambda Expression).
This code here reads the company with the id “company/1” and updates the name.
using (var documentStore = new DocumentStore { Url = "http://myurl:8080/" }) { using (var session = documentStore.OpenSession("testDB")) { var company = session.Query().Where(x => x.Id == "company/1").FirstOrDefault(); company.Name = "TVD"; session.SaveChanges(); } }
Example -> Read childs out of a document:
As you can see in the examples above, the employee (child) isn’t stored in a seperate document. (In a relational database you will create
a table for company and one for employee.)
If you want to retrieve ONLY the employees out of a company document, you have to write following code:
using (var session = documentStore.OpenSession("testDB")) { var emps = session.Query("Employees").Where(x => x.CompanyId == "company/1"); foreach (var e in emps) { // do something } }
This query excepts a result of type EmployeeResult. The parameter “Employees” is the name of a index, which is defined in the database.
The Employees index contains a match and a transform query.
Match LINQ:
from c in docs.Companies select new { CompanyId = c.Id }
Transform LINQ:
from c in results from e in c.Employees select new { CompanyId = c.Id, Employee = e }
The class EmployeeResult contains the company id an the employee object. This structure corresponds the result of the transform query.
public class EmployeeResult { public string CompanyId { get; set; } public Employee Employee { get; set; } }
(I’m still not sure if there’s an easier way for retrieving the “childs”/employees.)
Happy coding 😉