C#驱动及应用

添加dll引用

运行nuget命令:Install-Package mongocsharpdriver

即可安装MongoDb与C#相关的dll,主要有下面这4个dll。

Repository数据访问设计

1,BaseMongoDB

主要封装了连接数据库,获取数据库和获取集合的操作,如下代码。

namespace Wingon.Frameworks.MongoDb.Repository
{
    /// <summary>
    /// MongoDb基类
    /// 主要封装了创建数据库连接,获取数据库和获取集合的操作
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class BaseMongoDB<T> where T : class
    {
        public BaseMongoDB(string connectionString)
            : this(connectionString, null)
        {
        }

        public BaseMongoDB(string connectionString, string collectionName)
        {
            if (connectionString.IsNullOrEmpty())
            {
                connectionString = ConfigurationManager.ConnectionStrings["MongoTicketDB"].ConnectionString;
            }

            if (connectionString.IsNullOrEmpty())
            {
                throw new Exception("mongodb connectionString can not be empty!");
            }

            var mongoUrl = new MongoUrl(connectionString);
            DB = GetDatabaseFromUrl(mongoUrl);
            if (!string.IsNullOrEmpty(collectionName))
            {
                CollectionName = collectionName;
                this.Collection = DB.GetCollection<T>(collectionName);
            }
        }

        /// <summary>
        /// 依据连接字符串获取数据库
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private IMongoDatabase GetDatabaseFromUrl(MongoUrl url)
        {
            var client = new MongoClient(url);
            var db = client.GetDatabase(url.DatabaseName);
            return db;
        }

        /// <summary>
        /// 集合
        /// </summary>
        public IMongoCollection<T> Collection { get; }

        /// <summary>
        /// 数据库
        /// </summary>
        public IMongoDatabase DB { get; }

        /// <summary>
        /// 集合名称,默认为空
        /// </summary>
        public string CollectionName { get; } = string.Empty;
    }
}

2,MongoRepository

主要封装了对数据库的常用操作,比如增,删,改和查等,如下代码。

namespace Wingon.Frameworks.MongoDb.Repository
{
    /// <summary>
    /// MongoDb数据访问基类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="TKey"></typeparam>
    public class MongoRepository<T, TKey> : BaseMongoDB<T> where T : class
    {
        private readonly Type _keyType;

        protected MongoRepository(string connectionString = "", string collectionName = "")
            : base(connectionString, GetCollectionName(collectionName))
        {
            _keyType = typeof(TKey);
            if (_keyType != typeof(string) && _keyType != typeof(long) && _keyType != typeof(ObjectId))
            {
                throw new Exception("TKey must these type: string or long or ObjectId");
            }

            Initial();
        }

        /// <summary>
        /// 初始化
        /// 注册序列化器
        /// </summary>
        private void Initial()
        {
            try
            {
                var serializer = BsonSerializer.LookupSerializer(typeof(DateTime));
                if (serializer == null || serializer.GetType() != typeof(LocalTimeSerializer))
                {
                    // remove exist
                    var cacheFieldInfo = typeof(BsonSerializerRegistry).
                        GetField("_cache", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                    var _cacheTemp = cacheFieldInfo.GetValue(BsonSerializer.SerializerRegistry);
                    var _cache = _cacheTemp as ConcurrentDictionary<Type, IBsonSerializer>;
                    IBsonSerializer removeed;
                    _cache.TryRemove(typeof(DateTime), out removeed);

                    // add my owner
                    BsonSerializer.RegisterSerializer(typeof(DateTime), new LocalTimeSerializer());
                }
            }
            catch
            {
            }
        }

        /// <summary>
        /// 依据连接字符串创建数据库访问实例
        /// </summary>
        /// <param name="db"></param>
        /// <returns></returns>
        public static MongoRepository<T, TKey> CreateRepository(MongoDBs db = MongoDBs.MongoTicketDB)
        {
            var connStrName = Enum.GetName(typeof(MongoDBs), db);
            var connStr = ConfigurationManager.ConnectionStrings[connStrName].ConnectionString;
            return new MongoRepository<T, TKey>(connStr);
        }

        /// <summary>
        /// 获取集合名
        /// </summary>
        /// <param name="specifiedCollectionName"></param>
        /// <returns></returns>
        private static string GetCollectionName(string specifiedCollectionName)
        {
            string collectionName;

            if (!specifiedCollectionName.IsNullOrEmpty())
            {
                collectionName = specifiedCollectionName;
            }
            else
            {
                var att = Attribute.GetCustomAttribute(typeof(T), typeof(CollectionNameAttribute));
                collectionName = att != null ? ((CollectionNameAttribute)att).Name : typeof(T).Name;

                if (string.IsNullOrEmpty(collectionName))
                {
                    throw new ArgumentException("Collection name cannot be empty for this entity");
                }
            }

            return collectionName;
        }

        /// <summary>
        /// 判断集合是否存在
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public bool Exists(Expression<Func<T, bool>> predicate)
        {
            var count = this.Collection.Find(predicate).CountAsync().Result;
            return count > 0;
        }

        /// <summary>
        /// 依据id获取实体(文档)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T GetById(TKey id)
        {
            var filter = Builders<T>.Filter.Eq("_id", id);
            var result = this.Collection.Find(filter).FirstOrDefaultAsync().Result;
            return result;
        }

        /// <summary>
        /// 查询所有实体
        /// </summary>
        /// <returns></returns>
        public IEnumerable<T> GetAll()
        {
            return this.Collection.Find(new BsonDocument()).ToListAsync().Result;
        }

        /// <summary>
        /// 依据查询表达式来查询实体
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public IEnumerable<T> GetBy(Expression<Func<T, bool>> predicate)
        {
            return this.Collection.Find(predicate).ToListAsync().Result;
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="orderBy"></param>
        /// <returns></returns>
        public IEnumerable<T> GetByPaging(Expression<Func<T, bool>> predicate, int pageIndex, int pageSize, IList<OrderBy<T>> orderBy = null)
        {
            if (pageIndex < 1)
            {
                pageIndex = 1;
            }

            if (pageSize < 1)
            {
                pageSize = 15;
            }

            var data = this.Collection.Find(predicate);

            if (orderBy != null && orderBy.Count > 0)
            {
                var idx = 0;
                foreach (var sort in orderBy)
                {
                    idx++;
                    if (idx == 1)
                    {
                        data = sort.IsAscending ? data.SortBy(sort.Field) : data.SortByDescending(sort.Field);
                    }
                    else
                    {
                        var sortByData = data as IOrderedFindFluent<T, T>;
                        if (sortByData == null)
                        {
                            continue;
                        }

                        data = sort.IsAscending ? sortByData.ThenBy(sort.Field) : sortByData.ThenByDescending(sort.Field);
                    }
                }
            }

            var result = data.Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync().Result;

            return result;
        }

        /// <summary>
        /// 新增(单个)
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public void Insert(T entity)
        {
            AsyncHelper.RunSync(() => this.Collection.InsertOneAsync(entity));
        }

        /// <summary>
        /// 新增(批量)
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public void Insert(IEnumerable<T> entities)
        {
            AsyncHelper.RunSync(() => this.Collection.InsertManyAsync(entities));
        }

        /// <summary>
        /// 新增,从json字符串
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        public IList<BsonDocument> Insert(string json)
        {
            if (string.IsNullOrWhiteSpace(json))
            {
                return new List<BsonDocument>();
            }

            if (typeof(T) != typeof(BsonDocument))
            {
                throw new Exception("this method just for MogoRepository<BsonDocument> ");
            }

            var documents = new List<BsonDocument>();

            if (json.TrimStart().StartsWith("["))
            {
                var bsonDocument = BsonSerializer.Deserialize<BsonArray>(json);
                foreach (var b in bsonDocument)
                {
                    var bd = b.ToBsonDocument();
                    bd.Remove("$id");
                    documents.Add(bd);
                }
            }
            else
            {
                var bsonDocument = BsonSerializer.Deserialize<BsonDocument>(json);
                bsonDocument.Remove("$id");
                documents.Add(bsonDocument);
            }
            AsyncHelper.RunSync(()=> this.DB.GetCollection<BsonDocument>(this.CollectionName).InsertManyAsync(documents));

            return documents;
        }

        /// <summary>
        /// 更新(单个)
        /// </summary>
        /// <param name="entity"></param>
        /// <returns>返回影响的行数</returns>
        public long Update(T entity)
        {
            var filter = Builders<T>.Filter.Eq("_id", GetIdValue(entity));
            var replaceResult = this.Collection.ReplaceOneAsync(filter, entity).Result;
            return replaceResult.ModifiedCount;
        }

        /// <summary>
        /// 更新(批量)
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public long Update(IEnumerable<T> entities)
        {
            long modifiedCount = 0;
            foreach (var entity in entities)
            {
                var filter = Builders<T>.Filter.Eq("_id", GetIdValue(entity));
                var replaceResult = this.Collection.ReplaceOneAsync(filter, entity).Result;
                modifiedCount += replaceResult.ModifiedCount;
            }

            return modifiedCount;
        }

        /// <summary>
        /// 更新,如果不存在则新增
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool UpdateOrAdd(T entity)
        {
            SaveBigDataToLog(entity);

            if (Update(entity) < 1)
            {
                this.Collection.InsertOneAsync(entity);
            }

            return true;
        }

        /// <summary>
        /// 更新(局部更新)
        /// </summary>
        /// <param name="query"></param>
        /// <param name="columnValues">指定字段</param>
        /// <returns></returns>
        public long Update(Expression<Func<T, bool>> query, Dictionary<string, object> columnValues)
        {
            if (columnValues == null || columnValues.Count == 0)
            {
                throw new ArgumentException("Update Columns is Null!", nameof(columnValues));
            }

            var fileter = Builders<T>.Filter.Where(query);
            var update = Builders<T>.Update;
            UpdateDefinition<T> updateDefinination = null;
            columnValues.Keys.ToList().ForEach(x =>
            {
                updateDefinination = updateDefinination == null ? update.Set(x, columnValues[x]) : updateDefinination.Set(x, columnValues[x]);
            });
            var result = this.Collection.UpdateManyAsync<T>(query, updateDefinination).Result;

            return result.ModifiedCount;
        }

        /// <summary>
        /// 依据id删除数据(文档)
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public long Delete(TKey id)
        {
            var filter = Builders<T>.Filter.Eq("_id", id);
            var result = this.Collection.DeleteOneAsync(filter).Result;
            return result.DeletedCount;
        }

        /// <summary>
        /// 删除,依据实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public long Delete(T entity)
        {
            var filter = Builders<T>.Filter.Eq("_id", GetIdValue(entity));
            var result = this.Collection.DeleteOneAsync(filter).Result;
            return result.DeletedCount;
        }

        /// <summary>
        /// 删除,依据查询表达式
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public long Delete(Expression<Func<T, bool>> predicate)
        {
            var result = this.Collection.DeleteManyAsync<T>(predicate).Result;
            return result.DeletedCount;
        }

        /// <summary>
        /// 删除所有
        /// </summary>
        /// <returns></returns>
        public void RemoveAll()
        {
            AsyncHelper.RunSync(()=> this.Collection.DeleteManyAsync(new BsonDocument()));
        }

        #region Private method

        /// <summary>
        /// 获取实体的id
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        private object GetIdValue(T entity)
        {
            object result = null;

            if (typeof(T).IsSubclassOf(typeof(BaseMongoEntity<TKey>)))
            {
                var baseEntity = entity as BaseMongoEntity<TKey>;
                result = baseEntity.Id;
            }
            else if (typeof(T) == typeof(BsonDocument))
            {
                var bson = entity as BsonDocument;
                var objectId = bson["_id"];
                if (objectId != null && objectId.IsObjectId)
                {
                    result = objectId.AsObjectId;
                }
            }

            if (result == null)
            {
                throw new Exception("can not get Id (or ObjectId) from the entity, please check!");
            }

            return result;
        }

        /// <summary>
        /// 记录日志
        /// </summary>
        /// <param name="entity"></param>
        private void SaveBigDataToLog(T entity)
        {
            try
            {
                var dataJson = entity.ToJson();

                var saveDirector = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "VLogs", "PackageFH");
                saveDirector = Path.Combine(saveDirector, "BigDataLog");
                saveDirector = Path.Combine(saveDirector, DateTime.Now.ToString("yyyyMMdd"));
                if (!Directory.Exists(saveDirector))
                {
                    Directory.CreateDirectory(saveDirector);
                }
                var fileName = Path.Combine(saveDirector, $"{typeof(T).Name}_{Guid.NewGuid()}");
                File.WriteAllText(fileName, dataJson);
            }
            catch
            {
            }
        }
        #endregion
    }
}

Entity实体设计

因为mongoDb集合的主键主要有string,int和ObjectId(mongodb内置类型)这几种类型,所以封装了包含字段Id的泛型类型,如下代码。

namespace Wingon.Frameworks.MongoDb
{
    public interface IEntity<TKey>
    {
        TKey Id { get; set; }
    }
}
namespace Wingon.Frameworks.MongoDb
{
    [DataContract(IsReference = true)]
    [Serializable]
    public abstract class BaseMongoEntity<TKey> : IEntity<TKey>
    {
        [DataMember]
        public TKey Id { get; set; }
    }
}
namespace Wingon.Frameworks.MongoDb.Tests.Entity
{
    [DataContract(IsReference = true)]
    [Serializable]
    public class OrderLog: BaseMongoEntity<string>
    {
        [DataMember]
        public int OrderId { get; set; }

        [DataMember]
        public decimal OrderAmount { get; set; }

        [DataMember]
        public string Title { get; set; }

        [DataMember]
        public string Summary { get; set; }

        [DataMember]
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
        public DateTime? UpdatedDate { get; set; }

        [DataMember]
        [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
        public DateTime OrderDate { get; set; }
    }
}

需要注意的是,一般情形下,集合的主键就指定为默认的ObjectId类型,也可以手动指定为string和int类型。

时间: 2024-10-14 04:56:33

C#驱动及应用的相关文章

艰辛五天:Ubuntu14.04+显卡驱动+cuda+Theano环境安装过程

题记:从一开始不知道显卡就是GPU(虽然是学计算机的,但是我真的不知道-脑残如我也是醉了),到搞好所有这些环境前后弄了5天时间,前面的买显卡.装显卡和装双系统见另一篇博客装显卡.双系统,这篇主要记录我怎么配置后面的环境,虽然中间重装Ubuntu三次,后面安装过程也没差别. 基础平台:64-bit,Ubuntu14.04 1.安装NVIDIA驱动(参考技术文章,基本是复制啊,蟹蟹作者~) (1) 在官网下载NVIDIA驱动,根据自己买的型号选择下载,放到 /home/lvxia/ 目录下面,我下载

jdbc驱动jar导入eclipse

在使用JDBC编程时需要连接数据库,导入JAR包是必须的,导入其它的jar包方法同样如此,导入的方法是 打开eclipse 1.右击要导入jar包的项目,点properties 2.左边选择java build path,右边选择libraries 3.选择add External jars 4.选择jar包的按照路径下的确定后就行了. Java连接MySQL的最新驱动包下载地址 http://www.mysql.com/downloads/connector/j 有两种方法导入jar包,第一种

13.Linux键盘按键驱动 (详解)

版权声明:本文为博主原创文章,未经博主允许不得转载. 在上一节分析输入子系统内的intput_handler软件处理部分后,接下来我们开始写input_dev驱动 本节目标: 实现键盘驱动,让开发板的4个按键代表键盘中的L.S.空格键.回车键 1.先来介绍以下几个结构体使用和函数,下面代码中会用到 1)input_dev驱动设备结构体中常用成员如下: struct input_dev { void *private; const char *name; //设备名字 const char *ph

Linux-hexdump命令调试event驱动—详解(13)

hexdump: 查看文件的内容,比如二进制文件中包含的某些字符串,通常用来调试驱动用 1.调试 键盘驱动 讲解 当我们insmod挂载了键盘驱动后,找到键盘驱动被放在event1设备里, 此时没有按键按下,所以event1里面的数据是没有的,那么数据又是从来哪里来? 通过键盘驱动的read函数,若有按键按下,就会上传按键数据给用户层,此时的用户层就是hexdump 因为键盘驱动的input_handler 是:evdev_handler 所以键盘驱动的read函数是: evdev_handle

微软要做用云量挖掘机,以技术驱动数字化转型快公司

今年7月,首次更名为"Inspire"的微软WPC全球合作伙伴大会上,微软宣布将所有与合作伙伴相关的角色都重新整合为一个新的部门:统一商业合作伙伴部门(One Commercial Partner),并进行了一整套的组织和流程改组,以适应云计算时代的用户需求与"用云量"规律. 2017年9月12日,微软大中华区副总裁.全球渠道事业部总经理.商业客户事业部总经理包嘉峰与媒体分享了这两个月微软商业合作伙伴部转型以来,微软自身所发生的变化以及为客户所带来的价值.根据包嘉峰

STM32F4XX高效驱动篇2 I2C

说到I2C很多用过STMF10X硬件I2C方式的工程师,都感觉有点头痛.大部分还是使用软件模拟的方式,I2C由于一般的工作频率是400,100KHz.所以在平凡读取,或所读数据量大时,使用这模拟的方式,还是比较浪费CPU有效工作时间的. 在之前的使用I2C的经历中,主要是I2C死锁问题让我也困扰了一段时间.不过后来经过多方资料,最后还是把这个问题解决了.以下驱动程序已集成了此功能. 什么是死锁,在I2C主设备进行读写操作的过程中.主设备在开始信号后控制SCL产生8个时钟脉冲,然后拉低SCL信号为

STM32F4XX高效驱动篇1-UART

之前一直在做驱动方面的整理工作,对驱动的高效性有一些自己的理解这里和大家分享一下.并奉驱动程序,本程序覆盖uart1-8. 串口驱动,这是在每个单片机中可以说是必备接口.可以说大部分产品中都会使用,更有甚者一个产品中用到8个串口.这样一个高效的驱动是决定您产品优劣的关键因素.本文主要针对STM32F4XX系列芯片做的一个驱动接口层.以减少您在开发项目时驱动方面所花费时间,以及为程序达到高效的处理为目的. 从51,pic到现在的STM32,个人感觉STM32这方面做的非常突出,丰富的使用模式,强大

Qt编译好的OCI驱动下载

在上文,我累赘了一大堆,给大家写了一篇Qt如何编译OCI驱动,在这里自然就不再累赘了,直接附上编译好的文件供大家下载: <Qt5.3.1+OCI驱动下载地址> 有经济来源的请传送:http://download.csdn.net/detail/u012433546/9922424 无经济来源的请传送:链接:http://pan.baidu.com/s/1boKG9lH 密码:7yj5 <Qt5.3.2+OCI驱动下载地址> 有经济来源的请传送:http://download.csd

QT5.6.0+VS2015编译MQSQL(ACCESS)X64数据库驱动

QT5.6.0+VS2015编译MQSQL(ACCESS)数据库驱动 1 说明 l 不建议QT5.6.0使用ACCESS数据库.如果想使用轻量级的数据库,可以使用Sqlite数据库. QT想要访问Access.SQL Server等数据库可以通过ODBC的方式来访问,但是QT较高版本已不提供ODBC驱动库,需要自己编译.QT5.6.0编译出来的数据库驱动是64位,但是不建议安装Access数据库,微软本身也不建议安装64位office. PS:为什么QT5.6.0不编译32位数据库驱动:编译数据

MongoDB 官方C#驱动 封装 DbHelper

这里采用的是mongoDB官网推荐使用.net驱动: http://mongodb.github.io/mongo-csharp-driver/2.4/getting_started/quick_tour/ 官方的示例中 都是在代码里设置的Database 名称   已经习惯了  在连接字符串中设置了,翻看了下官方文档  终于找到在 字符串的方式设置方法了 原来的方式 MongoClient client = new MongoClient(connectionString); var db =