本人为巨杉数据库(开源NoSQL)写的C#驱动,支持Linq,全部开源,已提交github

一、关于NoSQL的项目需求

     这些年在做AgileEAS.NET SOA 中间件平台的推广、技术咨询服务过程之中,特别是针对我们最熟悉的医疗行业应用之中,针对大数据分析,大并发性能的需求,我们也在慢慢的引用NoSQL技术来满足数据分析与性能等多方面的需要,也进一步完善我们的SOA基石架构风格:

     在早些年,对NoSQL不是很了解这前,后端数据存储都是存储的单一的关系数据库之上,但是在很多时间,这并不是最优的,比如在医疗用户之中针对一个病人的相关数据展示,及相关性分析,关于数据库就不是最优的,另外一个,电子病历系统的之中的结构化/半结构化病历文档的存储、检索,以及更高级的应用,结构化病历数据挖掘,之前使用关系数据库存储或者使用文件存储,很难发挥病历数据的科研和统计、分析需求。

    在目前我们的医疗信息化应用之中,我们针对这两部分数据都引入了NoSQL存储,针对住院患者的领域相关性数据==》即病人聚合根对象相关数据,我们即在关系数据库以多表存储病人数据以及病人相关的医嘱、费用、检验、检查、护理等相关信息,同时我们也在NoSQL数据库存储患者的聚合根对象:

    在NoSQL数据库之中的存储:

    另外在电子病历应用之中,病历文档也是直接存入NoSQL之中。

    在接触巨杉数据库之前,我们一直使用MongoDB这款NoSQL产品,这是一款广为人知的NoSQL产品,使用者众多,C#的驱动也非常完善,案例也比比皆时。

三、关于巨杉(sequoiadb)数据库

     巨杉数据库是国人开发的一款企业级NoSQL数据库,目前已开源,官网http://www.sequoiadb.com/
初次了解到巨杉(sequoiadb)数据还是源于一个客户,因为我们项目一直使用MongoDB,客户就向我们提到巨杉(sequoiadb)数据库,说国内有人开发了这么一个NoSQL数据库,并且在平安银行有过成功应用,并且因为是国人开发,所以应该相比较MongoDB,应该能得到官方的支持,客户也和巨杉(sequoiadb)官方的人有过接触,官方也答应可以做一些支持。

     根据网上所公开的一些信息,巨杉(sequoiadb)数据库和MongoDB非常的接近,都是文档型数据库,同样的设计思路,集合和文档,同样的文档格式,Json/Bson。
根据最近一段时间的了解和完善C#驱动的过程来说,相对MongoDB,巨杉(sequoiadb)提供了更加方便的图形化部署和简单的Web管理界面:

     以下是SequoiaDB与MongoDB及其他NoSQL数据的功能对比:

     比较特别是的SequoiaDB支持事务和SQL语法,当然了,这两点在目前情况下我们都使用使用过。

四、关于SequoiaDB的C#驱动

     SequoiaDB官方提供C、C++、JAVA、C#、php、Python驱动以及REST架构风格的接口,据官方的说法是Java的驱动很成熟,但是C#的驱动很简单,只能支持最基本的Bson格式的接口,如下代码:

// Insert
            BsonDocument insertor = new BsonDocument();
            insertor.Add("Last Name", "Lin");
            insertor.Add("First Name", "Hetiu");
            insertor.Add("Address", "SYSU");
            BsonDocument sInsertor = new BsonDocument();
            sInsertor.Add("Phone", "10086");
            sInsertor.Add("EMail", "hetiu@yahoo.com.cn");
            insertor.Add("Contact", sInsertor);
            ObjectId insertID = (ObjectId)coll.Insert(insertor);
            Assert.IsNotNull(insertID);

            // Update
            DBQuery query = new DBQuery();
            BsonDocument updater = new BsonDocument();
            BsonDocument matcher = new BsonDocument();
            BsonDocument modifier = new BsonDocument();
            updater.Add("Age", 25);
            modifier.Add("$set", updater);
            matcher.Add("First Name", "Hetiu");
            query.Matcher = matcher;
            query.Modifier = modifier;
            coll.Update(query);

            // Query
            DBCursor cursor = coll.Query(query);
            Assert.IsNotNull(cursor);
            BsonDocument bson = cursor.Next();
            Assert.IsNotNull(bson);
            Assert.IsTrue(bson["First Name"].AsString.Equals("Hetiu"));
            Assert.IsTrue(bson["Age"].AsInt32.Equals(25));

            // Delete
            BsonDocument drop = new BsonDocument();
            drop.Add("Last Name", "Lin");
            coll.Delete(drop);
            query.Matcher = drop;
            cursor = coll.Query(query);
            Assert.IsNotNull(cursor);
            bson = cursor.Next();
            Assert.IsNull(bson);

     集合查询:

for (int i = 0; i < 10; ++i)
            {
                string date = DateTime.Now.ToString();
                BsonDocument insertor = new BsonDocument();
                insertor.Add("operation", "Query");
                insertor.Add("date", date);
                coll.Insert(insertor);
            }
            BsonDocument matcher = new BsonDocument();
            DBQuery query = new DBQuery();
            matcher.Add("operation", "Query");
            query.Matcher = matcher;
            query.ReturnRowsCount = 5;
            query.SkipRowsCount = 5;
            DBCursor cursor = coll.Query(query);
            Assert.IsNotNull(cursor);
            int count = 0;
            while (cursor.Next() != null)
            {
                ++count;
                BsonDocument bson = cursor.Current();
                Assert.IsNotNull(bson);
            }
            Assert.IsTrue(count == 5);

     官方的代码有点简单,这不符合我们写代码的风格,目前业务系统大量的使用对象操作和Linq处理,原始的Bson接口,这个不科学。

五、完善改造SequoiaDB的C#驱动

     即然官方的驱动太简单,不支持对象处理,也不支持Linq,很不科学,那么应该怎么办呢,其实第一个观点当然是放弃,我们原本使用MongoDB跑的好好的,为什么要给自己找事呢,但是出于项目运维的观点,以及支持国人产品的想法,最终决定自己完善和写一个。

     那么如何来写呢,当然是他山之石,可以攻玉,因为之前做MongoDB开发,原始的驱动配置我们的ORM跑起来也有一些问题,最早我们使用的非MongoDB的官方驱动,而是第三方驱动samus,不支持Decimal类型,但是我们项目之中有大量的Decimal类型,那么办呢,修改驱动,后来我们又换成了MongoDB的官方驱动,因为XmlIgnore标签和Id映射的问题也认真的读过MongoDB的官方驱动,对MongoDB的C#驱动比较熟悉。

     所以完善SequoiaDB的C#的思路就变成了结合SequoiaDB的原始驱动和MongoDB的官方驱动,提供一个类似于MongoDB驱动的操作风格的驱动,在SequoiaDB驱动的基础上提供了,直接操作C#对象的方案和支持Linq进行查询、修改、删除的功能。

     经本人完善修改之后的驱动的操作风格如下:

Sequoiadb sdb = new Sequoiadb("192.168.23.57:50000");
            sdb.Connect("", "");

            //求集合空间。
            var cs = sdb.GetCollecitonSpace("dbo");

            //求集合。
            var coll = cs.GetCollection<HFareDetail>();

            //执行数据插入。
            List<HFareDetail> vList =null;
            using (AgileHIS.Entities.DbEntities db = new AgileHIS.Entities.DbEntities())
            {
                vList = db.HFareDetails.ToList();
                //插入。
                foreach (var item in vList)
                {
                    coll.Insert(item);
                }
                System.Console.WriteLine(string.Format("insert {0} records", vList.Count));
                System.Console.ReadLine();
            }

            //按条件修改某一条数据的几个属性值。
            var v1 = vList.FirstOrDefault();
            v1.Name = string.Empty;
            v1.Cash = decimal.Zero;
            coll.Update(v1, p => p.ID == v1.ID);
            //按条件指量修改,指定某几个必,其他属性全部置空。
            coll.Update(p => new HFareDetail { Cash = decimal.Zero, Name = string.Empty, Price = decimal.Zero }, p => p.ChargeTime >DateTime.Now.AddDays(-1));
            //依据条件删除
            coll.Delete(p => p.ChargeTime > DateTime.Now.AddDays(-1));

            //求Count
            int count = coll.AsQueryable<HFareDetail>()
                .Where(p => p.SourceID==0)
                .Count();

            //Linq查询Take\Skip。
            var vList2 = coll.AsQueryable<HFareDetail>()
                .Where(p => p.CreateTime > DateTime.Now.Date.AddMonths(-12))
                .Skip(10).Take(1000)
                .ToList();
            System.Console.WriteLine(string.Format("query {0} records", vList.Count));

            //Linq查询过。
            var vFare = coll.AsQueryable<HFareDetail>()
                .Where(p => p.CreateTime > DateTime.Now.Date.AddMonths(-12))
                .FirstOrDefault();
            System.Console.WriteLine(vFare);

            //Linq\聚合运算,目前因为测试驱动报错,暂未实现
            var sum = coll.AsQueryable<HFareDetail>()
                .Where(p => p.CreateTime > DateTime.Now.Date.AddMonths(-12))
                .Sum(p => p.Cash);

            System.Console.ReadLine();

     看看,代码是不是很清爽,很方便了呢,没有了bson,只有对象,Linq。

六、SequoiaDB、MongoDB与AgileEAS.NET SOA整合

     AgileEAS.NET SOA之前只支持MongoDB,最近要支持SequoiaDB,我们就得考虑对原有代码的兼容,或者说,更希望自己的医疗系统能够在业务上同时支持MongoDB和SequoiaDB,达到使用环境之中不管是选择MongoDB还是选择SequoiaDB都是同样的代码,为此,我们在AgileEAS.NET SOA中间件之中定义了一个IStructDbProvider接口:

using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace EAS.Data
{
    /// <summary>
    /// 结构化数据库提供者接口定义。
    /// </summary>
    /// <remarks>
    /// 为AgileEAS.NET SOA 中间件NoSQL数据访问提供标准接口定义。
    /// </remarks>
    public interface IStructDbProvider
    {
        /// <summary>
        /// 打开连接。
        /// </summary>
        void Connect();

        /// <summary>
        /// 关闭连接。
        /// </summary>
        void Close();

        /// <summary>
        /// 连接是否打开。
        /// </summary>
        bool IsOpen { get; }

        /// <summary>
        /// 对象插入。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="item">对象实例。</param>
        void Insert<T>(T item) where T : class;

        /// <summary>
        /// 对象批量插入。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="items">对象实例。</param>
        void InsertBatch<T>(System.Collections.Generic.IEnumerable<T> items) where T : class;

        /// <summary>
        /// 根据条件执行更新操作。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="updater">更新表达式。</param>
        /// <param name="func">查询条件。</param>
        void Update<T>(Expression<Func<T, T>> updater, Expression<Func<T, bool>> func) where T : class;

        /// <summary>
        /// 根据条件执行更新操作。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="item">更新对象。</param>
        /// <param name="func">查询条件。</param>
        void Update<T>(T item, System.Linq.Expressions.Expression<Func<T, bool>> func) where T : class;

        /// <summary>
        /// 根据条件删除对象。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="func">条件表达式。</param>
        void Delete<T>(Expression<Func<T, bool>> func) where T : class;

        /// <summary>
        /// 求出Linq查询表达式。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <returns>对象表达式包装。</returns>
        IQueryableWarp<T> Linq<T>() where T : class;

        /// <summary>
        /// 根据条件查询数制。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="where">条件。</param>
        /// <param name="skip">跳过记录数。</param>
        /// <param name="take">取记录数。</param>
        /// <returns>查询结构。</returns>
        List<T> List<T>(Expression<Func<T, bool>> where, int skip, int take) where T : class;

        /// <summary>
        /// 根据条件求单条记录。
        /// </summary>
        /// <typeparam name="T">对象类型。</typeparam>
        /// <param name="where">条件。</param>
        /// <returns>对象实例。</returns>
        T Single<T>(Expression<Func<T, bool>> where) where T : class;
    }
}

     IStructDbProvider字面意思即为结构化数据访问提供者接口,本接口定义在EAS.MicroKernel.dll程序集之中,AgileEAS.NET SOA中间件同时提供了针对SequoiaDB和MongoDB数据库的IStructDbProvider实现,EAS.Data.MongoDbProvider和EAS.Data.SequoiaDbProvider,这两个实现类定义在EAS.Data.NoSQL.dll程序集之中。

     因为统计使用了IStructDbProvider接口,我们针对SequoiaDB和MongoDB的操作处理就统计成了如下代码:

var vContainer = EAS.Context.ContextHelper.GetContext().Container;
            var dbProvider = vContainer.GetComponentInstance("StructDbProvider") as IStructDbProvider;

            //执行数据插入。
            List<HFareDetail> vList = null;
            using (AgileHIS.Entities.DbEntities db = new AgileHIS.Entities.DbEntities())
            {
                vList = db.HFareDetails.ToList();
                //插入。
                foreach (var item in vList)
                {
                    dbProvider.Insert<HFareDetail>(item);
                }
                System.Console.WriteLine(string.Format("insert {0} records", vList.Count));
                System.Console.ReadLine();
            }

            //按条件修改某一条数据的几个属性值。
            var v1 = vList.FirstOrDefault();
            v1.Name = string.Empty;
            v1.Cash = decimal.Zero;
            dbProvider.Update<HFareDetail>(v1, p => p.ID == v1.ID);
            //按条件指量修改,指定某几个必,其他属性全部置空。
            dbProvider.Update<HFareDetail>(p => new HFareDetail { Cash = decimal.Zero, Name = string.Empty, Price = decimal.Zero }, p => p.ChargeTime > DateTime.Now.AddDays(-1));
            //依据条件删除
            dbProvider.Delete<HFareDetail>(p => p.ChargeTime > DateTime.Now.AddDays(-1));

            //求Count
            using (var queryWarp = dbProvider.Linq<HFareDetail>())
            {
                int count = queryWarp.Queryable
                .Where(p => p.SourceID == 0)
                .Count();

                //Linq查询Take\Skip。
                var vList2 = queryWarp.Queryable
                    .Where(p => p.CreateTime > DateTime.Now.Date.AddMonths(-12))
                    .Skip(10).Take(1000)
                    .ToList();
                System.Console.WriteLine(string.Format("query {0} records", vList.Count));

                //Linq查询过。
                var vFare = queryWarp.Queryable
                    .Where(p => p.CreateTime > DateTime.Now.Date.AddMonths(-12))
                    .FirstOrDefault();
                System.Console.WriteLine(vFare);

                //Linq\聚合运算,目前因为测试驱动报错,暂未实现
                var sum = queryWarp.Queryable
                    .Where(p => p.CreateTime > DateTime.Now.Date.AddMonths(-12))
                    .Sum(p => p.Cash);
            }

            System.Console.ReadLine();

     具体是使用SequoiaDB还是使用MongoDB由系统配置文件来决定,使用SequoiaDB:

<!--StructDb/SequoiaDb-->
      <object name="StructDbProvider" assembly="EAS.Data.NoSQL" type="EAS.Data.SequoiaDbProvider" LifestyleType="Thread">
        <property name="ConnectionString" type="string" value="192.168.23.57:50000"/>
        <property name="UserName" type="string" value=""/>
        <property name="Password" type="string" value=""/>
        <property name="CollectionSpace" type="string" value="his"/>
      </object>

     使用MongoDB。

<!--StructDb/MongoDb-->
      <object name="StructDbProvider" assembly="EAS.Data.NoSQL" type="EAS.Data.MongoDbProvider" LifestyleType="Thread">
        <property name="ConnectionString" type="string" value="mongodb://sa:sa@127.0.0.1:2222/his"/>
        <property name="DbName" type="string" value="his"/>
      </object>

七、SequoiaDB的C#驱动源代码托管、下载

     本人为SequoiaDB所写的C#驱动,已提交托管到github,项目地址https://github.com/agilelab/SequoiaDB.Charp,欢迎大家下载,也欢迎大家和本人一道完善本驱动。

八、联系我们

     敏捷软件工程实验室,是一家研究、推广和发展新技术,并致力于提供具有自主知识产权的业务基础平台软件,以及基于业务基础平台开发的管理软件的专业软件提供商。主要业务是为客户提供软件企业研发管理解决方案、企业管理软件开发,以及相关的技术支持,管理及技术咨询与培训业务。

     AgileEAS.NET SOA中间件平台自2004年秋呱呱落地一来,我就一直在逐步完善和改进,也被应用于保险、医疗、电子商务、房地产、铁路、教育等多个应用,但一直都是以我个人在推广,2010年因为我辞职休息,我就想到把AgileEAS.NET推向市场,让更多的人使用。

     我的技术团队成员都是合作多年的老朋友,因为这个平台是免费的,所以也没有什么收入,都是由程序员的那种理想与信念坚持,在此我感谢一起奋斗的朋友。

团队网站:http://www.agilelab.cn

AgileEAS.NET网站:http://www.smarteas.net

官方博客:http://eastjade.cnblogs.com

QQ:47920381,AgileEAS.NET

QQ群:113723486(AgileEAS SOA 平台)/上限1000人

199463175(AgileEAS SOA 交流)/上限1000人

212867943(AgileEAS.NET研究)/上限500人

147168308(AgileEAS.NET应用)/上限500人

172060626(深度AgileEAS.NET平台)/上限500人

116773358(AgileEAS.NET 平台)/上限500人

125643764(AgileEAS.NET探讨)/上限500人

193486983(AgileEAS.NET 平台)/上限500人

邮件:james@agilelab.cn,mail.james@qq.com,

电话:18629261335。

时间: 2024-10-26 10:11:10

本人为巨杉数据库(开源NoSQL)写的C#驱动,支持Linq,全部开源,已提交github的相关文章

Java中8个顶级开源NoSQL数据库!

Java中8个顶级开源NoSQL数据库! NoSQL Databases, Java, Terrastore, Neo4j, Voldemort, HBase, InfoGrid, HyperGraphDB, Perst, NeoDatis ODB NoSQL正在崛起.许多企业和用户已经将MySQL数据库替换成了NoSQL数据库.NoSQL使分析非结构化的数据变得更容易,因此开发者必须意识到存在于NoSQL世界中的趋势和工具. 1.Terrastore 新的文档存储技术可以提供先进的伸缩性和弹性

2011年5款备受关注的开源 NoSQL 数据库

1. 集中式缓存系统 memcached memcached是一套分布式的快取系统,当初是Danga Interactive为了LiveJournal所发展的,但目前被许多软件(如MediaWiki)所使用.这是一套开放源代码软件,以BSD license授权释出.memcached缺乏认证以及安全管制,这代表应该将memcached服务器放置在防火墙后.memcached的API使用三十二位元的循环冗余校验(CRC-32)计算键值后,将资料分散在不同的机器上.当表格满了以后,接下来新增的资料会

【独家】一文读懂非关系型数据库(NoSQL)

前言 NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL". 现代计算系统每天在网络上都会产生庞大的数据量.这些数据有很大一部分是由关系型数据库管理系统(RDBMSs)来处理,其严谨成熟的数学理论基础使得数据建模和应用程序编程更加简单. 但随着信息化的浪潮和互联网的兴起,传统的RDBMS在一些业务上开始出现问题.首先,对数据库存储的容量要求越来越高,单机无法满足需求,很多时候需要用集群来解决问题,而RDBMS由于要支持join,union等操作,一般不支持分

“巨杉数据库”获1000万美元B轮融资,DCM领投

今日,分布式数据库厂商SequoiaDB巨杉数据库对外宣布,已获得DCM领投的1000万美元B轮融资,启明创投跟投.在2014年12月,SequoiaDB曾获启明创投千万美元级A轮融资. 36氪此前报道过,SequoiaDB是新型分布式数据库,针对企业级用户,加入了其他NoSQL公司少有的事务操作功能,同时封装了用来支持Hadoop的MapReduce调用接口,此外,SequoiaDB还提供连接SQL的插件,让习惯用SQL某些功能的企业用户可以在SequoiaDB里对接SQL. 而就在近日,Se

SequoiaDB巨杉数据库与IBM共建Power Linux 生态系统

SequoiaDB巨杉数据库与IBM共建Power Linux 生态系统 2015年9月22日,主题为"开源重构世界 开发改变未来"的Linux开源生态系统联盟开发者大会在北京举行.作为全球首个基于Power平台的开源技术开发者盛会, 大会汇聚了国内外开源领域的代表和专家,通过丰富多样的开源应用案例,专家们向与会嘉宾分享了各自领域的最新研究进展,以及开源领域的新技术.新发展和新动向.会上,CSDN联手IBM及SequoiaDB等多家来自国内外开源领域的企业,启动了Linux开源生态系统

巨杉数据库获得1000万美元B轮融资

近日,新一代分布式数据库厂商SequoiaDB巨杉数据库宣布获得投资机构DCM领投的B轮融资1000万美元,A轮投资机构启明创投跟投. 在当前的资本寒冬之下,巨杉此次B轮融资,体现了投资界对于这家大数据基础软件公司发展的看好,此次融资也成为国内新一代分布式数据库领域最大的一笔投融资. 目前,BAT等互联网巨头也正在积极布局大数据云计算.根据IDC预测,未来5年全球用于云计算服务的支出将增长3倍,云计算行业的整体增长速度将是传统IT行业增长速度的6倍. 巨杉数据库联合创始人王涛接受南方日报采访时表

全面梳理关系型数据库和 NoSQL 的使用情景

今天我将对常见关系型数据库以及NoSQL的使用场景做一个详细的分析和比较.希望对大家以后的数据库选型有所帮助. 目录 数据库场景比较 MySQL还是PostgreSQL? MongoDB 键值(Key-Value)数据库 Cassandra 图数据库(Neo4j) 公司业务适合使用的数据库 数据库场景比较 MySQL还是PostgreSQL? 1.如果你的应用对数据的完整性和严肃性要求不高,但是追求处理的高速度.例如论坛和社区,你应该使用MySQL. 2.如果你的应用是一个严肃的商业应用,对数据

关系型数据库和NOSQL数据库对比

关系型数据库,是建立在关系模型基础上的数据库,其借助于集合代数等数学概念和方法来处理数据库中的数据.主流的 oracle.DB2.MS SQL Server和mysql都属于这类传统数据库. NoSQL数据库,全称为Not Only SQL,意思就是适用关系型数据库的时候就使用关系型数据库,不适用的时候也没有必要非使用关系型数据库不可,可以考虑使用更加合适的数据存储.主要分为临时性键值存储(memcached.Redis).永久性键值存储(ROMA.Redis).面向文档的数据库(MongoDB

php 数据采集-php如何连结数据库,怎么写代码

问题描述 php如何连结数据库,怎么写代码 php mysql如何连结数据库,怎么写代码,坐等高手,搞了好久都不成功 解决方案 http://www.cnblogs.com/JamyWong/archive/2009/06/03/1495499.html 解决方案二: PHP数据库连接代码 解决方案三: PHP数据库连接代码 解决方案四: mysql_select("localhost","root","root"); mysql_selectd