Mongodb的Samus驱动

最近开始学习Mongodb方面的东西..

看到有很多博主都说MongoDB的第三方驱动 Samus 对Linq的支持比较好..能够降低学习的成本..所以就想从这里开始..

但是弊端在我学习了一半的时候才发现..很严重..Samus驱动对数据库的操作没有返回值..增删改都没有..只有查询有结果..

这在很多时候都不能允许的..因为我们必须知道这一步是否操作成功才能够安全的进入下一步..

不过我还是硬着头皮写完了一套增删改查的工具方法..在这里共享一下..也作为一个记录..

至于具体放在什么地方使用..就要智者见智了..譬如操作日志的存储..

废话不多说..直接上代码..

这里边有部分代码都是从别处Copy来的..但却又自成体系..有作者路过的请留言..

Entity类

EntityBase:  是所有实体对象的基类..要求所有的实体都继承于他

Person:   实体对象. 不必再定义_ID..属性必须显示定义..也就是说必须都写{get;set;} 因为我们后边有一个OrderBy动态排序要求使用类的公共属性

    /// <summary>
    /// 对象基类..所有对象都继承于该类
    /// </summary>
    public class EntityBase
    {
        public string _id { get; set; }
    }

    /// <summary>
    /// 用户实体类  实体类里不用定义ID..基类里定义过了 <例>
    /// </summary>
    class Person : EntityBase
    {
        public Person()
        {
            //创建新对象时..直接自生产新 _ID
            _id = MongoUtil.NewObjectId();
        }
        public string NN { get; set; }
        public int Age { get; set; }
    }

DBHelper类   (比较长)

增删改:  这里边Insert  Delete  Update都写成了扩展方法..可以直接使用

可以这样用..  Person.DB_Delete()  来删除  支持 List<Person>.DB_Delete() 删除

    具体的可以仔细查看一下..

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using MongoDB;
using MongoDB.Util;
using MongoDB.GridFS;
using MongoDB.Commands;
using MongoDB.Results;
using System.Linq.Expressions;
using System.Reflection;

namespace Sam
{
    public static class MongoU
    {
        #region //Query

        /// <summary>
        /// 查找对象
        /// </summary>
        /// <param name="document">筛选条件</param>
        /// <returns></returns>
        public static TT FindOne<TT>(Document document) where TT : EntityBase
        {
            using (Mongo mon = new Mongo(Config.ConnString))
            {
                mon.Connect();
                var table = mon.GetDatabase(Config._dbName).GetCollection<TT>(typeof(TT).Name);
                return table.FindOne(document);
            }
        }

        /// <summary>
        /// 查找对象
        /// </summary>
        /// <param name="predicate">Lambda 表达式</param>
        /// <returns></returns>
        public static TT FindOne<TT>(Expression<Func<TT, bool>> predicate) where TT : EntityBase
        {
            using (Mongo mon = new Mongo(Config.ConnString))
            {
                mon.Connect();
                var table = mon.GetDatabase(Config._dbName).GetCollection<TT>(typeof(TT).Name);
                var result = table.Find<TT>(predicate).Documents;
                return result.Count() != 0 ? result.First<TT>() : null;
            }
        }

        /// <summary>
        /// 查找列表
        /// </summary>
        /// <param name="document">筛选条件</param>
        /// <returns></returns>
        public static List<TT> Find<TT>(Document document) where TT : EntityBase
        {
            using (Mongo mon = new Mongo(Config.ConnString))
            {
                mon.Connect();
                var table = mon.GetDatabase(Config._dbName).GetCollection<TT>(typeof(TT).Name);
                return table.Find(document).Documents.ToList();
            }
        }

        /// <summary>
        /// 查找列表
        /// </summary>
        /// <param name="predicate">Lambda 表达式</param>
        /// <returns></returns>
        public static List<TT> Find<TT>(Expression<Func<TT, bool>> predicate) where TT : EntityBase
        {
            using (Mongo mon = new Mongo(Config.ConnString))
            {
                mon.Connect();
                var table = mon.GetDatabase(Config._dbName).GetCollection<TT>(typeof(TT).Name);
                return table.Find<TT>(predicate).Documents.ToList();
            }
        }

        /// <summary>
        /// 分页查找
        /// </summary>
        /// <param name="Exp1">Lambda 表达式</param>
        /// <param name="OrderFiled">排序列</param>
        /// <param name="isAsc">是否正序排列  True为Asc  Flase为Desc</param>
        /// <param name="PageIndex">页码</param>
        /// <param name="PageCount">页尺寸</param>
        /// <returns></returns>
        public static List<TT> FindByPage<TT>(Expression<Func<TT, bool>> Exp1, string OrderFiled, bool isAsc, int PageIndex, int PageCount) where TT : EntityBase
        {
            using (Mongo mon = new Mongo(Config.ConnString))
            {
                mon.Connect();
                var table = mon.GetDatabase(Config._dbName).GetCollection<TT>(typeof(TT).Name);
                //动态属性排序
                return table.Linq().Where(Exp1).OrderByDynamic<TT>(OrderFiled, isAsc).Skip((PageIndex - 1) * PageCount).Take(PageCount).ToList();
            }
        }
        #endregion

        #region //Delete

        /// <summary>
        /// 根据规则删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="predicate"></param>
        public static void DB_Delete<TT>(this TT source) where TT : EntityBase
        {
            if (source == null) return;
            using (Mongo mon = new Mongo(Config.ConnString))
            {
                mon.Connect();
                var table = mon.GetDatabase(Config._dbName).GetCollection<TT>(typeof(TT).Name);
                table.Remove(new Document().Add("_id", source._id), true);
            }
        }

        /// <summary>
        /// 根据规则删除
        /// </summary>
        /// <typeparam name="TT"></typeparam>
        /// <param name="predicate"></param>
        public static void DB_Delete<TT>(this List<TT> source) where TT : EntityBase
        {
            if (source == null | source.Count() == 0) return;
            using (Mongo mon = new Mongo(Config.ConnString))
            {
                mon.Connect();
                var table = mon.GetDatabase(Config._dbName).GetCollection<TT>(typeof(TT).Name);
                var list = new List<string>();
                foreach (var item in source)
                {
                    list.Add(item._id);
                }
                table.Remove(new Document().Add("_id", MongoDB.Op.In(list.ToArray())), true);

            }
        }

        public static void DB_Delete<TT>(Document document) where TT : EntityBase
        {
            using (Mongo mon = new Mongo(Config.ConnString))
            {
                mon.Connect();
                var table = mon.GetDatabase(Config._dbName).GetCollection<TT>(typeof(TT).Name);
                table.Remove(document, true);
            }
        }

        public static void DB_Delete<TT>(Expression<Func<TT,bool>> Exp1) where TT : EntityBase
        {
            using (Mongo mon = new Mongo(Config.ConnString))
            {
                mon.Connect();
                var table = mon.GetDatabase(Config._dbName).GetCollection<TT>(typeof(TT).Name);
                table.Remove(Exp1, true);
            }
        }

        #endregion

        #region //Modify

        /// <summary>
        /// 修改单个对象  根据_id修改
        /// </summary>
        /// <param name="obj"></param>
        public static void DB_Update<TT>(this TT source) where TT : EntityBase
        {
            using (Mongo mon = new Mongo(Config.ConnString))
            {
                mon.Connect();
                var table = mon.GetDatabase(Config._dbName).GetCollection<TT>(typeof(TT).Name);
                table.Update(source, new { _id = source._id }, true);
            }
        }
        #endregion

        #region //Add

        /// <summary>
        /// 添加一条数据到 Mongo
        /// </summary>
        /// <typeparam name="T">添加的对象类型</typeparam>
        /// <param name="entity">添加的对象</param>
        /// <returns>操作结果 来源为判断异步任务是否因异常或者取消动作而完成,是的话返回False</returns>
        public static void DB_Insert<TT>(this TT source) where TT : EntityBase
        {
            using (Mongo mon = new Mongo(Config.ConnString))
            {
                mon.Connect();
                var table = mon.GetDatabase(Config._dbName).GetCollection<TT>(typeof(TT).Name);
                table.Insert(source, true);
            }
        }

        /// <summary>
        /// 同时添加多条数据到 Mongo
        /// </summary>
        /// <typeparam name="TT">添加的对象类型</typeparam>
        /// <param name="entities">对象的集合</param>
        /// <returns>操作结果 来源为判断异步任务是否因异常或者取消动作而完成,是的话返回False</returns>
        public static void DB_Insert<TT>(IEnumerable<TT> entities) where TT : EntityBase
        {
            using (Mongo mon = new Mongo(Config.ConnString))
            {
                mon.Connect();
                var table = mon.GetDatabase(Config._dbName).GetCollection<TT>(typeof(TT).Name);
                table.Insert(entities, true);
            }
        }
        #endregion
    }
}

MongoUtil  自动生成ObjectId

静态方法:  String _id= MongoUtil.NewObjectId()  可以生成出来新的不会重复Id

namespace Sam
{
    internal static class MongoUtil
    {
        private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        private static readonly object _innerLock = new object();
        private static int _counter;
        private static readonly byte[] _machineHash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(Dns.GetHostName()));
        private static readonly byte[] _processId = BitConverter.GetBytes(Process.GetCurrentProcess().Id);

        public static string NewObjectId()
        {
            var oid = new byte[12];
            var copyidx = 0;

            Array.Copy(_machineHash, 0, oid, copyidx, 3);
            copyidx += 3;

            Array.Copy(_processId, 0, oid, copyidx, 2);
            copyidx += 2;

            Array.Copy(BitConverter.GetBytes(GenerateTime()), 0, oid, copyidx, 4);
            copyidx += 4;

            Array.Copy(BitConverter.GetBytes(GenerateCounter()), 0, oid, copyidx, 3);

            StringBuilder strBuilder = new StringBuilder();
            foreach (byte bt in oid)
            {
                strBuilder.AppendFormat("{0:X2}", bt);
            }

            return strBuilder.ToString().ToLower();
        }

        private static int GenerateTime()
        {
            var now = DateTime.UtcNow;
            var nowtime = new DateTime(Epoch.Year, Epoch.Month, Epoch.Day,now.Hour, now.Minute, now.Second, now.Millisecond);
            var diff = nowtime - Epoch;
            return Convert.ToInt32(Math.Floor(diff.TotalMilliseconds));
        }

        private static int GenerateCounter()
        {
            lock (_innerLock)
            {
                return _counter++;
            }
        }
    }

}

OrderBy 或  OrderByDescending  的动态排序

    public static class Extended
    {

        #region //动态排序

        /// <summary>
        /// 动态OrderBy
        /// </summary>
        /// <typeparam name="TT">TT要求是继承了EntityBase的实体类型</typeparam>
        /// <param name="source">操作源</param>
        /// <param name="propertyStr">要用来排序的属性名</param>
        /// <param name="isAsc">正序排 True  倒叙排 False</param>
        /// <returns></returns>
        public static IQueryable<TT> OrderByDynamic<TT>(this IQueryable<TT> source, string propertyStr, bool isAsc) where TT : class
        {
            ParameterExpression param = Expression.Parameter(typeof(TT), "c");
            PropertyInfo property = typeof(TT).GetProperty(propertyStr);
            Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property);
            LambdaExpression le = Expression.Lambda(propertyAccessExpression, param);
            Type type = typeof(TT);
            MethodCallExpression resultExp = Expression.Call(typeof(Queryable), (isAsc ? "OrderBy" : "OrderByDescending"), new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(le));
            return source.Provider.CreateQuery<TT>(resultExp);
        }
        #endregion
    }

大的框架就是这样..具体的使用时可以分层..就是老三层啦..

我这里是直接对象到数据库的操作的..

大家写的时候可以仔细弄一弄..

时间: 2024-10-25 22:24:14

Mongodb的Samus驱动的相关文章

Samus驱动中的Document条件

今天要说一个东西就是Samus驱动里的 Document  和他的一个子类 Op 在Samus驱动的增删改查方法中都有这类的参数传递.. 大致的使用方法是这样.. MongoU.Find<Person>(new Document().Add("Age",1)); 这是查询Person表中Age==1 的数据.. 但是这有个问题..那就是不知道Document如何传递 类似   Age>20  或者  Age<>20 之类的条件.. 直到后来我发现了Op对象

mongodb c# driver(驱动)介绍及CURD

mongodb c# driver(驱动)介绍 目前基于C#的mongodb驱动有两种,分别是官方驱动(下载地址)和samus驱动(下载地址). 本次我们只演示官方驱动的使用方法. 官方驱动文档查看 第一步:引用驱动dll 引用驱动有两种方式: 1. 根据上面的下载地址下载对应的版本,然后引用到项目中. 2. 在项目的引用上右击->管理NuGet程序包(首先确保安装了nuget扩展包)->联机搜索官方驱动dll(搜索条件是 “Official MongoDB”)->安装成功后会引用3个d

8天学通MongoDB——第八天 驱动实践

作为系列的最后一篇,得要说说C#驱动对mongodb的操作,目前驱动有两种:官方驱动和samus驱动,不过我个人还是喜欢后者, 因为提供了丰富的linq操作,相当方便. 官方驱动:https://github.com/mongodb/mongo-csharp-driver/downloads.下载后,还提供了一个酷似msdn的帮助文档. samus驱动:https://github.com/samus/mongodb-csharp/downloads. 下面就具体看看samus驱动,https:

【转载】8天学通MongoDB——第八天 驱动实践

作为系列的最后一篇,得要说说C#驱动对mongodb的操作,目前驱动有两种:官方驱动和samus驱动,不过我个人还是喜欢后者, 因为提供了丰富的linq操作,相当方便. 官方驱动:https://github.com/mongodb/mongo-csharp-driver/downloads.下载后,还提供了一个酷似msdn的帮助文档. samus驱动:https://github.com/samus/mongodb-csharp/downloads. 下面就具体看看samus驱动,https:

MongoDB官方C#驱动中查询条件Query用法

http://www.cnblogs.com/viprx/archive/2012/09/06/2673693.html MongoDB条件查询的基本语法. Query.All("name", "a", "b");//通过多个元素来匹配数组  Query.And(Query.EQ("name", "a"), Query.EQ("title", "t"));//同时满足

centos7.2 安装mongoDB C/C++驱动

系统:centos7.2 说明所有源码放在 1.准备mongoDB C/C++驱动依赖 yum -y install epel-release yum install -y git  gcc gcc-c++  openssl openssl-devel make texinfo patch  imake wget perl-Test-Harness perl-Thread-Queue  perl-Data-Dumper help2man cyrus-sasl-devel glib-devel g

MongoDB之PHP驱动

1. 下载mongo的PHP驱动 注意版本:我们使用的是Apache服务器的PHP,PHP版本是-5.4,VC6,线程安全.所以要找对应的php-mongo.dll才行! 下载地址:http://github.com/mongodb/mongo-php-driver 2.查看PHP版本: D:\Apache Software Foundation\Apache2.2\php snapshot.txt里面有.Version: 5.4.30 3.详细安装:windows下的MongoDB的PHP驱动

通过mongodb客户端samus代码研究解决查询慢问题

最近有项目需要用到mongodb,于是在网上下载了mongodb的源码,根据示例写了测试代码,但发现一个非常奇怪的问题:插入记录的速度比获取数据的速度还要快,而且最重要的问题是获取数据的速度无法让人接受.     测试场景:主文档存储人员基本信息,子文档一存储学生上课合同数据集合,这个集合多的可达到几百,子文档二存储合同的付款记录集合,集合大小一般不会超过50.根据人员ID查询人员文档,序列化后的大小为180K不到,但消耗的时间在400ms以上.    我的主要问题在于不能接收获取一个180K的

MongoDB的Java驱动使用整理 (转)

MongoDB Java Driver 简单操作 一.Java驱动一致性 MongoDB的Java驱动是线程安全的,对于一般的应用,只要一个Mongo实例即可,Mongo有个内置的连接池(池大小默认为10个).  对于有大量写和读的环境中,为了确保在一个Session中使用同一个DB时,我们可以用以下方式保证一致性:  DB mdb = mongo.getDB('dbname');  mdb.requestStart(); // // 业务代码 // mdb.requestDone(); DB和