NoSqlJsonFile - .NET 轻量级文档存储






4.81/5 (9投票s)
一种类似 NoSQL 的 JSON 格式文档存储。
引言
NoSqlJsonFile
顾名思义,它被设计成一种类似 NoSQL 的 JSON 格式文档存储,类似于 mongoDB——一个用 C++ 编写的文档存储。NoSqlJsonFile 是一个用 C# 编写的开源项目,面向希望获得真正轻量级但功能强大的存储的 .NET 开发人员。NoSqlJsonFile
被设计成返回可枚举/泛型列表类型,因此您可以使用强大的 .NET LINQ/Lambda 表达式来操作数据。如果您是 .NET 开发人员,并且喜欢 mongoDB,那么您将爱上 NoSqlJsonFile
。
那么,为什么选择 NoSqlJsonFile?
基于文件系统和面向文档
- 关系数据库中的每个表在 NoSqlJsonFile 中都代表一个目录或文件夹。
- 关系数据库中的每一行在 NoSqlJsonFile 中都代表一个文件。
- 它支持一对多关系和递归关系。
- 文件以 JSON 格式存储。
- 基于文件系统的优点是它不需要任何特殊的程序或引擎。
便携且轻量
- 它旨在成为一个单一源代码文件,以便开发人员可以复制它并为不同的项目修改它。
无需设置,只需将 NoSqlJsonFile.cs 文件包含在您的项目中,然后继承它即可
- 您所要做的就是继承
NoSqlJsonFile
类,然后就可以开始使用了!
使用代码
这是一个简单的 CRUD 示例,用于创建客户文档存储。
创建文档存储
要创建新的文档存储,首先需要定义一个类,然后像下面这样简单地为属性赋值。Save()
方法是从 NoSqlJsonFile
类继承的,调用 Save()
方法后,将生成唯一的 ID,然后文档将默认保存为项目目录下的文件(可以通过在 app.config 中定义 FilePath 来更改)。文件将被命名为“Customer94554F9D47E0425B97EBC13614F36CD5”,位于 NoSqlJsonFiles 目录下。
Customer customer = new Customer();
customer.FirstName = "Anna";
customer.LastName = "Lee";
customer.Save();
对于类定义,首先必须继承您的类自 NoSqlJsonFile 类,然后将[DataContract]
属性添加到您的类。所有属性都必须附加[DataMember]
属性,否则属性将被忽略。属性名必须严格是自动属性,即 XXX{get;set;}。
[DataContract]
class Customer : NoSqlJsonFile<Customer>
{
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
}
如果您从项目的 bin\Debug 或 bin\Release 文件夹打开文件,您可以在名为 NoSqlJsonFiles\Customer94554F9D47E0425B97EBC13614F36CD5 的文件夹中找到该文件。文件以 JSON 格式保存,以 UniqueId 作为文档名。
{"DateModfied":"\/Date(1363055984263+1100)\/","UniqueId":"Customer94554F9D47E0425B97EBC13614F36CD5","FirstName":"Anna","LastName":"Lee"}
列出文档存储
只需调用继承的 List()
或 Enumerable()
方法即可。
foreach (Customer c in Customer.List())
{
Console.WriteLine( c.FirstName + " " + c.LastName);
}
更新文档存储中的文档
var customer = Customer.Get("Customer94554F9D47E0425B97EBC13614F36CD5");
customer.FirstName = "Annie";
customer.Save();
从文档存储中删除文档
Customer.Delete("Customer94554F9D47E0425B97EBC13614F36CD5");
或者,如果该类是 NoSqlJsonFile 的实例,则调用customer.Delete();
采购订单应用程序示例
我们将使用一个简单的采购订单作为示例,描述如下:
一个客户与一个订单存在一对多的关系,因为一个客户可以下多个订单,但一个给定的订单只能由一个客户下。
一个订单与订单详情存在一对多的关系,因为每个订单详情项包含订购价格和数量。
订单详情与产品存在一对一的关系,每个订单详情都指向一个产品。
产品包含商品的描述和单价。
[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);
// 5 percents off on a product order if the total quantity is greater than 10
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; }
}
方法和属性
在 Customer 类中,我们创建了一个名为 CreateNewOrder() 的方法,该方法创建一个新订单并返回订单实例。我们还定义了一个名为ProcessEmailSuccessful
的字段,这是我们的编程空间属性,如果不定义[DataMember]
,它将不会保存到文件中。在 Order 类中,我们定义了一个名为 AddProductDetail() 的方法,该方法创建 OrderDetail 并将产品及其订单价格和数量添加到 Order 本身。我们还定义了一个私有字段 _discountPriceOnQuantity
,由于未定义为[DataMember]
,因此该字段不会保存到文件中。让我们开始吧
在这个例子中,我们将生成一个客户和两个产品。一个客户将订购这两个产品。
我们要创建的客户是Jerry Liang,详细信息如下:
客户:Jerry LiangFullName | Jerry Liang |
电子邮件 | example@example.com |
地址 | 20 Albert Rd Strathfield NSW Australia |
ActiveMember | true |
生成它的代码。
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();
我们还需要两个产品,一个叫 HTC One,一个叫 iPad3。
产品:HTC OneProductName | HTC One |
单价 | 400.50 |
产品:iPad3
ProductName | iPad3 |
单价 | 550.95 |
生成它们 的代码。
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();
让我们看看是否已成功将它们添加到我们的文档存储中。首先,我们可以列出所有内容,看看它们是否在那里。
//I am only interested in Active Members
foreach (var customer in Customer.List().Where(c =>c.ActiveMember))
{
Console.WriteLine(customer.FullName);
}
foreach (var product in Product.List())
{
Console.WriteLine(product.ProductName);
}
如果没有什么问题,我们就可以在控制台输出中看到名称。现在我想让 Jerry Liang 购买 HTC One 和 iPad3 产品,这可以通过调用 Customer 类中定义的 CreateNewOrder()
方法来实现。
//Firstly to search the customer by using his full name.
var customer = Customer.List().FirstOrDefault(c => c.FullName == "Jerry Liang");
//and then search the HTC One and iPad3 by using thier product names
var htcOne = Product.List().FirstOrDefault(p => p.ProductName == "HTC One");
var ipad = Product.List().FirstOrDefault(p => p.ProductName == "iPad3");
//after that call CreateNewOrder() method from Customer class to get an Order then call AddProductDetail() method from Order class
var orderId = customer.CreateNewOrder().AddProductDetail(htcOne, 500f, 10).AddProductDetail(ipad, 650.95f, 15).UniqueId;
//Finally we just call Save() method from customer instance to save all changes.
customer.Save();
//if you want to know the order, you can use
var order = Order.Get(orderId);
foreach (var orderDetail in order.OrderDetails)
{
Console.WriteLine(orderDetail.OrderedProduct + " " + orderDetail.OrderedPrice + " " + orderDetail.Quantity);
}
关注点
在本介绍中,我没有提及 NoSqlJsonFile 的任何实现。它大量使用了 .NET 反射和序列化库。此外,如果您有兴趣并希望做出贡献,请在 Github https://github.com/jerry27syd/NoSqlJsonFileProject 上 fork 我。
历史
2013 年 3 月 14 日:添加采购订单示例
2013 年 3 月 13 日:初始版本