Introduction
NoSqlJsonFile
as the name implies, it is designed to be NoSQL-like document store
in JSON format, similar to mongoDB - a C++ written document store. NoSqlJsonFile
is an open source written in C# for .NET developers who want a true lightweight
but powerful storage. NoSqlJsonFile
is designed to return enumerable/ generic list
type, so you can utilise powerful .NET LINQ/Lambda expression to manipulate data.
If you are a .NET Developer and you like mongoDB then you will be in love
with NoSqlJsonFile
.
So Why NoSqlJsonFile?
File system based and Document-oriented
- Each table in relational database represents a directory or folder in NoSqlJsonFile.
- Each row in relational database represents a file in NoSqlJsonFile.
- It supports one to many relationship andrecursive relationship.
- The file is stored in JSON Format.
- The benefit of file system based is that
it requires no special program or engine on top.
Portable and lightweight
- It is intended to be a single source code file so that the developer can copy it
and modify it for different projects.
No setup required, just include NoSqlJsonFile.cs file in your project then inherit
it
- All you need to do is just to inherit the
NoSqlJsonFile
class and off
you go!
Using the code
Here is a simple CRUD example to create a customer document store.
Create a document store
To create a new document store, firstly, you need to define a class and then simply
assign values to the properties as follows. Save()
method is inherited
from NoSqlJsonFile
class, once Save()
method is called,
the Unique Id is generated and then the document is saved as a file under your project
directory by default (can be changed by define FilePath in your app.config).The
file will be named like "Customer94554F9D47E0425B97EBC13614F36CD5"under
NoSqlJsonFiles directory.
Customer customer = new Customer();
customer.FirstName = "Anna";
customer.LastName = "Lee";
customer.Save();
For the class definition, first of all you must inherit your class from NoSqlJsonFile
class and then attach[DataContract]
attribute to your class. All properties
must be attached with the[DataMember]
attribute else the properties
will be ignored. the property name is strictly an Auto Property i.e.,
XXX{get;set;}.
[DataContract]
class Customer : NoSqlJsonFile<Customer>
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
}
If you open the file from your project bin\Debug or bin\Release.
You can find the file under folder called NoSqlJsonFiles\Customer94554F9D47E0425B97EBC13614F36CD5.The
file is saved as in JSON format with The UniqueId as the document name.
{"DateModfied":"\/Date(1363055984263+1100)\/","UniqueId":"Customer94554F9D47E0425B97EBC13614F36CD5","FirstName":"Anna","LastName":"Lee"}
List a document store
Simply call the inherited List()
or Enumerable()
method.
foreach (Customer c in Customer.List())
{
Console.WriteLine( c.FirstName + " " + c.LastName);
}
Update a document from document store
var customer = Customer.Get("Customer94554F9D47E0425B97EBC13614F36CD5");
customer.FirstName = "Annie";
customer.Save();
Delete a document from document store
Customer.Delete("Customer94554F9D47E0425B97EBC13614F36CD5");
Or if the class is an instance of NoSqlJsonFile then call
customer.Delete();
Purchase Order Application Example
We will use a simple Purchase Order as our example which is describe as follows:
A Customer has a one to many relationship with a Order because a customer can place
many orders, but a given order can be placed by only one customer.
An Order has a one to many relationship with OrderDetail because each OrderDetail
item contains an ordered price and quantity.
An OrderDetail has a one to one relationship to Product, each OrderDetail refers
to one Product.
A Product contains the description of item and unit price.
[DataContract]
public class Customer : NoSqlJsonFile<Customer>
{
[DataMember]
public string FullName { get; set; }
[DataMember]
public string Email { get; set; }
[DataMember]
public string Address { get; set; }
[DataMember]
public bool ActiveMember { get; set; }
[DataMember]
public List<Order> Orders { get; set; }
public bool ProcessEmailSuccessful {get; set;}
public Order CreateNewOrder(string description = "")
{
if (Orders == null)
{
Orders = new List<Order>();
}
var order = new Order();
order.OrderedDate = DateTime.Now;
order.Description = description;
Orders.Add(order);
return order;
}
}
[DataContract]
public class Order : NoSqlJsonFile<Order>
{
[DataMember]
public DateTime OrderedDate { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public List<OrderDetail> OrderDetails { get; set; }
private int _discountPriceOnQuantity = 10;
public Order AddProductDetail(Product product, float price, int quantity)
{
if (OrderDetails == null)
{
OrderDetails = new List<OrderDetail>();
}
var orderDetail = new OrderDetail();
orderDetail.OrderedProduct = product;
orderDetail.OrderedPrice = price;
orderDetail.Quantity = quantity;
OrderDetails.Add(orderDetail);
if (quantity > _discountPriceOnQuantity){
orderDetail.OrderedPrice = orderDetail.OrderedPrice * 0.95f;
}
return this;
}
}
[DataContract]
public class OrderDetail : NoSqlJsonFile<OrderDetail>
{
[DataMember]
public Product OrderedProduct { get; set; }
[DataMember]
public float OrderedPrice { get; set; }
[DataMember]
public int Quantity { get; set; }
}
[DataContract]
public class Product : NoSqlJsonFile<Product>
{
[DataMember]
public string ProductName { get; set; }
[DataMember]
public float UnitPrice { get; set; }
}
Methods and Properties
In Customer class, we have created a method called CreateNewOrder(), this method
creates a new order and return the instance of order. We also define a field called
ProcessEmailSuccessful
this is our programming space property, without
defining
[DataMember]
it will not be saved to file. In Order class,
we defined a method called AddProductDetail(), this method creates an OrderDetail
and adds a product with order price and qauntity to the Order itself. We also define
a private field called
_discountPriceOnQuantity
, this field will not
be saved to file as it is not defined as
[DataMember]
.
Let's do it
In the example, we are going to generate one customer and two products. One customer
will make an order with two products.
The customer we want to create is Jerry Liang with the following details
Customer: Jerry Liang
FullName
|
Jerry Liang
|
Email
|
example@example.com
|
Address
|
20 Albert Rd Strathfield NSW Australia
|
ActiveMember
|
true
|
The code to generate it.
var customer = new Customer();
customer.FullName = "Jerry Liang";
customer.Email = "example@example.com";
customer.Address = "20 Albert Rd Strathfield NSW Australia";
customer.ActiveMember = true;
customer.Save();
We also need two products one is called HTC One and iPad3.
Product: HTC One
ProductName
|
HTC One
|
UnitPrice
|
400.50
|
Product: iPad3
ProductName
|
iPad3
|
UnitPrice
|
550.95
|
The code to generate them.
var product = new Product();
product.ProductName = "HTC One";
product.UnitPrice = 400.50f;
product.Save();
var product = new Product();
product.ProductName = "iPad3";
product.UnitPrice = 550.95f;
product.Save();
Let's see if we have added them successfully in our document store. Firstly, we
could list them all see if they are there.
foreach (var customer in Customer.List().Where(c =>c.ActiveMember))
{
Console.WriteLine(customer.FullName);
}
foreach (var product in Product.List())
{
Console.WriteLine(product.ProductName);
}
If nothing goes wrong, we can see the name in our console output. And now I would
like to Jerry Liang to make a purchase of HTC One and iPad3 products, it can be
done by calling the method CreateNewOrder()
which is defined in Customer
class.
var customer = Customer.List().FirstOrDefault(c => c.FullName == "Jerry Liang");
var htcOne = Product.List().FirstOrDefault(p => p.ProductName == "HTC One");
var ipad = Product.List().FirstOrDefault(p => p.ProductName == "iPad3");
var orderId = customer.CreateNewOrder().AddProductDetail(htcOne, 500f, 10).AddProductDetail(ipad, 650.95f, 15).UniqueId;
customer.Save();
var order = Order.Get(orderId);
foreach (var orderDetail in order.OrderDetails)
{
Console.WriteLine(orderDetail.OrderedProduct + " " + orderDetail.OrderedPrice + " " + orderDetail.Quantity);
}
Points of Interest
In this introduction, I have not mentioned any implmenation of NoSqlJsonFile. It
is heavily developed by using .NET Reflection and Serialization library. Also if
you are interested and would like to make a contribution please fork me at Github https://github.com/jerry27syd/NoSqlJsonFileProject
History
14th March 2013: Adding Purchase Order Example
13th March 2013: Initial Version