zoukankan      html  css  js  c++  java
  • MongoDB.Driver 2.4以上版本 在.NET中的基本操作

    MongoDB.Driver是操作mongo数据库的驱动,最近2.0以下版本已经从GitHub和Nuget中移除了,也就是说.NET Framework4.0不再能从官方获取到MongoDB的驱动了,其次MongoDB.Driver2.0开始API变更巨大,本文不适用MongoDB.Driver2.0以下版本,亦不适用.NET Framework4.5以下版本

    要在.NET中使用MongoDB,就必须引用MongoDB的驱动,使用Nuget安装MongoDB.Driver是最方便的,目前Nuget支持的MongoDB程序包有对.NET Framework4.5以上版本的依赖

    安装完成之后会在引用中新增三个MongoDB的程序集引用,其中MongoDB.Driver.Core在2.0版本以下是没有的

    先构建一个实体基类,因为Mongo要求每个文档都有唯一Id,默认为ObjectId类型(根据时间Mac地址Pid算出来的,类似GUID,适用于分布式),在这个基类中添加Id属性

    using MongoDB.Bson;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MongoTest
    {
        /// <summary>
        /// 自定义类型Id
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public abstract class BaseEntity<T>
        {
            public T Id { get; set; }
        }
        /// <summary>
        /// Mongo默认填充ObjectId类型的Id
        /// </summary>
        public abstract class DefaultIdEntity : BaseEntity<ObjectId>
        {
        }
    }
    View Code

    开始构建数据库访问类DbContext

    using MongoDB.Driver;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MongoTest
    {
        public class DbContext
        {
            public readonly IMongoDatabase _db;
            public DbContext()
            {
                //此为开启验证模式 必需使用用户名 密码 及指定登陆的数据库 可采用,分割连接多个数据库
                var client = new MongoClient("mongodb://root:123456@192.168.20.54:27017/admin");
                //未开启验证模式数据库连接
                // var client = new MongoClient("mongodb://127.0.0.1:27017"); 
                //指定要操作的数据库
                _db = client.GetDatabase("mytest");
            }
    
            private static string InferCollectionNameFrom<T>()
            {
                var type = typeof(T);
                return type.Name;
            }
    
            public IMongoCollection<T> Collection<T, TId>() where T : BaseEntity<TId>
            {
                var collectionName = InferCollectionNameFrom<T>();
                return _db.GetCollection<T>(collectionName);
            }
            /// <summary>
            /// 实体类名和数据库中文档(关系型数据库中的表)名一致时使用
            /// </summary>
            public IMongoCollection<T> Collection<T>() where T : DefaultIdEntity
            {
                var collectionName = InferCollectionNameFrom<T>();
                return _db.GetCollection<T>(collectionName);
            }
    
            public IMongoCollection<T> Collection<T, TId>(string collectionName) where T : BaseEntity<TId>
            {
                return _db.GetCollection<T>(collectionName);
            }
            /// <summary>
            /// 实体类名和数据库中文档(关系型数据库中的表)不一致时使用,通过collectionName指定要操作得文档
            /// </summary>
            public IMongoCollection<T> Collection<T>(string collectionName) where T : DefaultIdEntity
            {
                return _db.GetCollection<T>(collectionName);
            }
        }
    }
    View Code

    现有数据库数据 文档book 包含数据如下

    开始构建与文档对应的实体,mongo是文档数据库,对单词得大小写是敏感得,所以构建的实体的字段也应该是小写的,有点不符合习惯

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MongoTest
    {
        public class book : DefaultIdEntity
        {
            public string title { get; set; }
            public double price { get; set; }
            public string author { get; set; }
            public string publisher { get; set; }
            public int saleCount { get; set; }
        }
    }
    View Code

    现在开始增删查改操作,其中查找和删除的filter参数有两种形式,lambda和Definition

    using MongoDB.Driver;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MongoTest
    {
        public class OperatDb
        {
            static IMongoCollection<book> bookDao;
            static OperatDb()
            {
                bookDao = new DbContext().Collection<book>();
            }
    
            public static void Excute()
            {
                Console.WriteLine();
                QueryAll();
                Console.WriteLine();
                Query();
                Console.WriteLine();
                Insert();
                Console.WriteLine();
                QueryAll();
                Console.WriteLine();
                Update();
                Console.WriteLine();
                Delete();
                Console.WriteLine();
                QueryAll();
                Console.ReadKey();
            }
            public static void QueryAll()
            {
                var books = bookDao.Find(x => true).ToList();
                foreach (var item in books)
                {
                    Console.WriteLine(item.ToString());
                }
            }
    
            public static void Query(System.Linq.Expressions.Expression<Func<book, bool>> filter = null)
            {
                if (filter == null) filter = x => x.author == "韩寒";
                var books = bookDao.Find(filter).ToList();
                foreach (var item in books)
                {
                    Console.WriteLine(item.ToString());
                }
            }
    
            public static void Update()
            {
                var filter = Builders<book>.Filter.Eq(x => x.title, "悲伤逆流成河");
                var book = bookDao.Find(filter).FirstOrDefault();
                Console.WriteLine("更新前:{0}", book.ToString());
                var update = Builders<book>.Update.Set(x => x.publisher, "新时代出版社")
                                                  .Set(x => x.price, 35)
                                                  .Inc(x => x.saleCount, 10);
                var result = bookDao.UpdateOne(filter, update);
                Console.WriteLine("IsAcknowledged:{0} MatchedCount:{1} UpsertedId:{2} IsModifiedCountAvailable:{3} ModifiedCount:{4}",
                    result.IsAcknowledged, result.MatchedCount, result.UpsertedId, result.IsModifiedCountAvailable, result.ModifiedCount);
                book = bookDao.Find(filter).FirstOrDefault();
                Console.WriteLine("更新后:{0}", book.ToString());
            }
    
            public static void Delete()
            {
                var result = bookDao.DeleteOne(x => x.title == "悲伤逆流成河");
                Console.WriteLine("DeletedCount:{0} IsAcknowledged:{1} ", result.DeletedCount, result.IsAcknowledged);
            }
    
            public static void Insert()
            {
                var bookInfo = new book
                {
                    Id = new MongoDB.Bson.ObjectId(),
                    author = "郭敬明",
                    price = 10.00,
                    publisher = "春风文艺出版社",
                    saleCount = 0,
                    title = "悲伤逆流成河"
                };
                bookDao.InsertOne(bookInfo);
            }
        }
    }
    View Code

     因为我对book类的ToString方法进行了重写,所以输出结果如下

    上面都是用的数据库和实体字段名一致的情况,如果不一致怎么办呢,Xml和Json等序列化都有标签特性可以用别名,Bson肯定也会有,新建BookInfo实体如下

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MongoTest
    {
        public class BookInfo : DefaultIdEntity
        {
            public string Title { get; set; }
            public double Price { get; set; }
            public string Author { get; set; }
            public string Publisher { get; set; }
            public int SaleCount { get; set; }
        }
    }
    View Code

    将上面执行操作的book全部替换成BookInfo试试,发现没报错,再去数据库看看会发现,数据库新增了一个文档,我们预期得结果是要操作在book上,显然这不是我们想要的

    现在将调用Collection调用改为指定collectionName为book的形式

            static IMongoCollection<BookInfo> bookDao;
            static OperatDb()
            {
                bookDao = new DbContext().Collection<BookInfo>("book");
            }

    再次运行程序,发现报错了,文档节点和实体字段不匹配

    现在给BookInfo的字段都加上Bson的标签特性

    using MongoDB.Bson.Serialization.Attributes;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace MongoTest
    {
        public class BookInfo : DefaultIdEntity
        {
            [BsonElement("title")]
            public string Title { get; set; }
            [BsonElement("price")]
            public double Price { get; set; }
            [BsonElement("author")]
            public string Author { get; set; }
            [BsonElement("publisher")]
            public string Publisher { get; set; }
            [BsonElement("saleCount")]
            public int SaleCount { get; set; }
        }
    }
    View Code

    现在一切正常了,显示结果和之前的一样就不再贴图了,有子文档的数据操作与此类似,譬如有如下数据

    构建实体如下

      public class Director : Entity
        {
            [BsonElement("name")]
            public string Name { get; set; }
            [BsonElement("country")]
            public string Country { get; set; }
            [BsonElement("age")]
            public int Age { get; set; }
            [BsonElement("movies")]
            public List<Movie> Movies { get; set; }
        }
        public class Movie
        {
            [BsonElement("name")]
            public string Name { get; set; }
            [BsonElement("year")]
            public int Year { get; set; }
        }
    View Code
  • 相关阅读:
    网站安全策略
    防止表单重复提交的几种策略
    Laravel5中防止XSS跨站攻击的方法
    PHP + ORACLE 远程连接数据库环境配置
    iview table表格内容为数组或者对象的子元素时问题讨论
    jquery中 $(xxx).each() 和 $.each()的区别,以及enter键一键登录
    vue.js 强行赋值、刷新数组或者对象 方法之 $.set()
    vue 组件,以及组件的复用
    vue 和 jquery混合使用
    JS清除空格之trim()方法
  • 原文地址:https://www.cnblogs.com/jasonlwings/p/7447448.html
Copyright © 2011-2022 走看看