.net Core MongoDB用法演示

C#驅動MongoDB的本質是將C#的操做代碼轉換爲mongo shell,驅動的API也比較簡單明瞭,方法名和js shell的方法名基本都保持一致,熟悉mongo shell後學習MongoDB的C#驅動是十分輕鬆的,直接看幾個demo吧。mongodb

0.準備測試數據

使用js shell添加一些測試數據,以下:shell

use myDb
db.userinfos.insertMany([
   {_id:1, name: "張三", age: 23,level:10, ename: { firstname: "san", lastname: "zhang"}, roles: ["vip","gen" ]},
   {_id:2, name: "李四", age: 24,level:20, ename: { firstname: "si", lastname: "li"}, roles:[ "vip" ]},
   {_id:3, name: "王五", age: 25,level:30, ename: { firstname: "wu", lastname: "wang"}, roles: ["gen","vip" ]},
   {_id:4, name: "趙六", age: 26,level:40, ename: { firstname: "liu", lastname: "zhao"}, roles: ["gen"] },
   {_id:5, name: "田七", age: 27, ename: { firstname: "qi", lastname: "tian"}, address:'北京' },
   {_id:6, name: "周八", age: 28,roles:["gen"], address:'上海' }
])

1 添加(InsertOne,InsertMany)

  安裝nuget包(或者執行命令  Install-Package MongoDB.Driver)數據庫

 

而後就可使用C#操做MongoDB數據庫了,看一個添加的demo:學習

 class Program
    {
        static void Main(string[] args)
        {
            //鏈接數據庫
            var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
            //獲取database
            var mydb = client.GetDatabase("myDb");
            //獲取collection
            var collection = mydb.GetCollection<BsonDocument>("userinfos");
            //待添加的document
            var doc = new BsonDocument{
                { "_id",7 },
                { "name", "吳九" },
                { "age", 29 },
                { "ename", new BsonDocument
                    {
                        { "firstname", "jiu" },
                        { "lastname", "wu" }
                    }
                }
            };
            //InsertOne()添加單條docment
            collection.InsertOne(doc);
        }
    }

執行完成後,查看在NoSQLBooster中查詢,看到已經添加成功了:測試

 

咱們也能夠是用 collection.InsertMany(IEnumerable<BsonDocument> docs) 來批量添加docment,這裏就再也不演示了。ui

2  查詢(Find,Filter,Sort,Projection)

1.簡單查詢(Find、Filter)

 查找name=「吳九"的記錄spa

var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
//獲取database
var mydb = client.GetDatabase("myDb");
//獲取collection
var collection = mydb.GetCollection<BsonDocument>("userinfos");
//Fileter用於過濾,如查詢name = 吳九的第一條記錄
var filter = Builders<BsonDocument>.Filter;
//Find(filter)進行查詢
var doc = collection.Find(filter.Eq("name", "吳九")).FirstOrDefault();
Console.WriteLine(doc);

查詢結果以下:3d

 

若是咱們想查詢全部的記錄,能夠設置過濾器爲空,代碼爲: var docs = collection.Find(filter.Empty).ToList(); code

2.AND查詢

查詢年齡大於25且小於28的記錄blog

//鏈接數據庫
var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
//獲取database
var mydb = client.GetDatabase("myDb");
//獲取collection
var collection = mydb.GetCollection<BsonDocument>("userinfos");
//查詢25<age<28的記錄
var filter = Builders<BsonDocument>.Filter;
var docs = collection.Find(filter.Gt("age", 25) & filter.Lt("age", 28)).ToList();
docs.ForEach(d => Console.WriteLine(d));

 查詢結果以下:

 

3 OR查詢

查詢年齡小於25或年齡大於28的記錄

var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
//獲取database
 var mydb = client.GetDatabase("myDb");
//獲取collection
var collection = mydb.GetCollection<BsonDocument>("userinfos");
//查詢年齡小於25或年齡大於28的記錄
var filter = Builders<BsonDocument>.Filter;
var docs = collection.Find(filter.Lt("age", 25) | filter.Gt("age", 28)).ToList();
docs.ForEach(d => Console.WriteLine(d));

查詢結果以下:

 

4 字段存在(Exists)

查詢包含address字段的全部記錄

//鏈接數據庫
var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
//獲取database
var mydb = client.GetDatabase("myDb");
//獲取collection
var collection = mydb.GetCollection<BsonDocument>("userinfos");
//查詢存在address字段的記錄
var filter = Builders<BsonDocument>.Filter;
var docs = collection.Find(filter.Exists("address")).ToList();
docs.ForEach(d => Console.WriteLine(d));

查詢結果以下:

 

5 排序(Sort)

查詢年齡小於26歲的記錄,並按年齡倒序排列

//鏈接數據庫
var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
//獲取database
var mydb = client.GetDatabase("myDb");
//獲取collection
var collection = mydb.GetCollection<BsonDocument>("userinfos");
//查詢age<26的記錄,按年齡倒序排列
var filter = Builders<BsonDocument>.Filter;
var sort = Builders<BsonDocument>.Sort;
var docs = collection.Find(filter.Lt("age", 26))//過濾
                     .Sort(sort.Descending("age")).ToList();//按age倒序
docs.ForEach(d => Console.WriteLine(d));

查詢結果以下:

6 查詢指定字段(Projection)

MongoDB查詢會默認返回_id字段,若是要不返回_id字段可使用Exclude("_id")將其排除。

//鏈接數據庫
var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
//獲取database
var mydb = client.GetDatabase("myDb");
//獲取collection
var collection = mydb.GetCollection<BsonDocument>("userinfos");
//查詢age<26的記錄 包含name age 排除 _id
var project = Builders<BsonDocument>.Projection;
var filter = Builders<BsonDocument>.Filter;
var docs = collection.Find(filter.Lt("age", 26))//過濾
                     .Project(project.Include("name")//包含name
                                     .Include("age")//包含age
                                     .Exclude("_id")//不包含_id
                           ).ToList();
docs.ForEach(d => Console.WriteLine(d));

查詢結果:

 

 3 修改(UpdateOne,UpdateMany)

1 修改單條記錄(UpdateOne)

修改符合過濾條件的第一條記錄,例子:將張三的年齡改爲18歲

//鏈接數據庫
var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
//獲取database
var mydb = client.GetDatabase("myDb");
//獲取collection
var collection = mydb.GetCollection<BsonDocument>("userinfos");
var filter = Builders<BsonDocument>.Filter;
var update = Builders<BsonDocument>.Update;
var project = Builders<BsonDocument>.Projection;
//將張三的年齡改爲18
collection.UpdateOne(filter.Eq("name", "張三"), update.Set("age", 18));
//查詢張三的記錄
var doc = collection.Find(filter.Eq("name", "張三"))
                    .Project(project.Include("age").Include("name"))
                    .FirstOrDefault();
Console.WriteLine(doc);

執行結果:

2 修改多條記錄(UpdateMany)

UpdateMany會修改全部符合過濾條件的記錄,例子:將全部年齡小於25的記錄標記爲young(若是沒有mark字段會自動添加)

//鏈接數據庫
var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
//獲取database
var mydb = client.GetDatabase("myDb");
//獲取collection
var collection = mydb.GetCollection<BsonDocument>("userinfos");
var filter = Builders<BsonDocument>.Filter;
var update = Builders<BsonDocument>.Update;
var project = Builders<BsonDocument>.Projection;
//將張三的年齡改爲18
collection.UpdateOne(filter.Eq("name", "張三"), update.Set("age", 18));
//查詢張三的記錄
var doc = collection.Find(filter.Eq("name", "張三"))
                    .Project(project.Include("age").Include("name"))
                    .FirstOrDefault();
Console.WriteLine(doc);

查詢結果以下,能夠看到age<25的記錄的mark字段值爲young:

 

4 刪除(DeleteOne和DeleteMany)

刪除操做比較簡單,DeleteOne用於刪除符合過濾條件的第一條記錄,DeleteMany用於刪除全部符合過濾條件的記錄。

1 刪除單條記錄(DeleteOne)

 刪除名字爲張三的記錄

//鏈接數據庫
var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
//獲取database
var mydb = client.GetDatabase("myDb");
//獲取collection
var collection = mydb.GetCollection<BsonDocument>("userinfos");
var filter = Builders<BsonDocument>.Filter;
var project = Builders<BsonDocument>.Projection;
//刪除名字爲張三的記錄
collection.DeleteOne(filter.Eq("name", "張三"));
var docs = collection.Find(filter.Empty)
                .Project(project.Include("age").Include("name").Include("mark"))
                .ToList();
docs.ForEach(d => Console.WriteLine(d));

執行結果以下,咱們看到張三的記錄已經被刪除了:

2  刪除多條記錄(DeleteMany)

刪除全部年齡大於25歲的記錄

//鏈接數據庫
var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
//獲取database
var mydb = client.GetDatabase("myDb");
//獲取collection
var collection = mydb.GetCollection<BsonDocument>("userinfos");
var filter = Builders<BsonDocument>.Filter;
var project = Builders<BsonDocument>.Projection;
//刪除age>25的記錄
DeleteResult result = collection.DeleteMany(filter.Gt("age", 25));
Console.WriteLine($"一共刪除了{result.DeletedCount}條記錄");
var docs = collection.Find(filter.Empty)
                .Project(project.Include("age").Include("name").Include("mark"))
                .ToList();
docs.ForEach(d => Console.WriteLine(d));

執行結果以下,全部年齡大於25歲的記錄都被刪除了:

5 類型映射

1 簡單例子

 有時候咱們要讓查詢的結果映射到咱們的實體類中去,實現這個需求也十分簡單,mongoDB支持自動映射,直接使用泛型便可,看一個(清空數據db.userinfos.remove({}),重新初始化js腳本):

 class Program
    {
        static void Main(string[] args)
        {
            //鏈接數據庫
            var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
            //獲取database
            var mydb = client.GetDatabase("myDb");
            //獲取collection
            var collection = mydb.GetCollection<Userinfo>("userinfos");
            var filter = Builders<Userinfo>.Filter;
            var sort = Builders<Userinfo>.Sort;
            List<Userinfo> userinfos = collection.Find(filter.Lt("age", 25))    //查詢年齡小於25歲的記錄
                                                 .Sort(sort.Descending("age"))  //按年齡進行倒序
                                         .ToList();
            //遍歷結果
            userinfos.ForEach(u => Console.WriteLine($"姓名:{u.name},年齡:{u.age},英文名:{u.ename.firstname} {u.ename.lastname}"));
            Console.ReadKey();
        }

        /// <summary>
        /// 用戶類
        /// </summary>
        public class Userinfo
        {
            public int _id { get; set; }//id
            public string name { get; set; }//姓名
            public int age { get; set; }//年齡
            public int level { get; set; }//等級
            public Ename ename { get; set; }//英文名
            public string[] roles { get; set; }//角色
            public string address { get; set; }//地址
        }

        /// <summary>
        /// 英文名
        /// </summary>
        public class Ename
        {
            public string firstname { get; set; }
            public string lastname { get; set; }
        }


執行結果以下:

 

2 經常使用屬性  

上邊的例子僅僅用了基本的自動化映射,使用基本的自動化映射時:類和Bson中的字段必須嚴格一致(_id除外,能夠自動映射到_id/id/Id),且Bson中的每個字段在實體類中都必須有一個對應的字段,否則就會拋出異常,這就形成咱們可能要寫一個很是龐大的實體類,並且類中的字段命名也要嚴格和Bson中的字段一致。這些限制對咱們開發來講是不能接受的,這裏咱們採用mongoDriver中的一些屬性改進一下上邊的代碼,以下:

 class Program
    {
        static void Main(string[] args)
        {
            //鏈接數據庫
            var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
            //獲取database
            var mydb = client.GetDatabase("myDb");
            //獲取collection
            var collection = mydb.GetCollection<Userinfo>("userinfos");

            var filter = Builders<Userinfo>.Filter;
            var sort = Builders<Userinfo>.Sort;
            List<Userinfo> userinfos = collection.Find(filter.Lt("age", 25))    //查詢年齡小於25歲的記錄
                                                 .Sort(sort.Descending("age"))  //按年齡進行倒序
                                         .ToList();
            //遍歷結果
            userinfos.ForEach(u =>
            {
                Console.WriteLine($"編號:{u.userId},姓名:{u.name},年齡:{u.age},英文名:{u.ename?.ming} {u.ename?.xing},性別:{u.gender}");
                Console.WriteLine($"其餘屬性:{u.otherprops}");
                Console.WriteLine();
            });

            Console.ReadKey();
        }

        /// <summary>
        /// 用戶類
        /// </summary
        //[BsonIgnoreExtraElements]
        public class Userinfo
        {
            [BsonId]
            public int userId { get; set; }//id
            public string name { get; set; }//姓名
            public int age { get; set; }//年齡
            public Ename ename { get; set; }//英文名
            [BsonDefaultValue('')]
            public char gender { get; set; }
            [BsonIgnore]
            public string nickname { get; set; }//暱稱
            [BsonExtraElements]
            public BsonDocument otherprops { get; set; }//其餘屬性
        }
        /// <summary>
        /// 英文名
        /// </summary>
        public class Ename
        {
            [BsonElement("firstname")]
            public string ming { get; set; }
            [BsonElement("lastname")]
            public string xing { get; set; }
        }

執行結果以下:

 

這裏用到了幾個經常使用的屬性,做用以下:

  BsonId修飾的字段對應BsonDocument中的_id;

  BsonDefaultValue(value)用於指定默認值;

  BsonIgnore表示不映射,即便BsonDocument中包含該字段也不會賦值給屬性;

  BsonExtraElements修飾的字段用於存儲沒有映射到類中的其餘屬性;

  BsonElement能夠指定修飾的屬性映射到BsonDocument中的哪一個字段,

還有一些其餘的屬性,具體能夠參考官方文檔。

3 MongoDB使用Linq查詢 

 MongoDB的驅動支持Linq查詢,用法十分簡單,引用  usingMongoDB.Driver.Linq;  後,使用  collection.AsQueryable()  獲取IMongoQueryable<T>實例,而後就可使用Linq對這個IMongoQueryable<T>進行查詢了。

  使用過EF的小夥伴應該都瞭解IQueryable+Linq的查詢默認不是將整個結果集當即加載到內存中,而是延遲加載的,即只有使用結果時(如 在執行First,Last,Single,Count,ToList等)纔會將Linq轉換成Sql,在數據庫中執行查詢操做。相似的,在使用IMongoQueryable<T>+Linq進行查詢時默認也是延遲加載的,在須要使用查詢結果時,驅動會將Linq轉換成聚合管道命令(aggregation pipeline),如Linq中的Where被轉換成$watch,Join轉換爲$lookup,Skip和Take轉換爲$skip和$limit等等,而後在Mongodb中執行這些管道命令獲取結果,看一個栗子咱們就會輕鬆地掌握了。

首先添加一些測試數據:

//添加學生數據
db.students.insertMany([
    {"no":1, "stuName":"jack", "age":23, "classNo":1},
    {"no":2, "stuName":"tom", "age":20, "classNo":2},
    {"no":3, "stuName":"hanmeimei", "age":22, "classNo":1},
    {"no":4, "stuName":"lilei", "age":24, "classNo":2}
    ])
        
//添加班級數據
db.classes.insertMany([
    {"no" : 1,"clsName" : "A班"},
    {"no" : 2,"clsName" : "B班"}
    ])

這裏查找了兩組數據:①基本查詢:查找年齡大於22歲的學生;②鏈接查詢:查詢各個學生的學號、姓名、班級名。例子比較簡單,直接看代碼吧

namespace ConsoleAppCore
{
    using System;
    using MongoDB.Bson;
    using MongoDB.Bson.Serialization.Attributes;
    using MongoDB.Driver;
    using MongoDB.Driver.Linq;
    using System.Collections.Generic;
    class Program
    {
        static void Main(string[] args)
        {
            //鏈接數據庫
            var client = new MongoClient("mongodb://root:root@192.168.100.3:27017/");
            //獲取database
            var mydb = client.GetDatabase("myDb");
            //獲取collection
            var stuCollection = mydb.GetCollection<Student>("students");
            var clsCollection = mydb.GetCollection<Classx>("classes");
            //查找年齡大於22的學生
            Console.WriteLine("-------------查找年齡大於22的學生列表--------------");
            //1.query語法
            List<Student> stuList1 = (from stu in stuCollection.AsQueryable()
                                      where stu.age > 22
                                      select stu).ToList();
            //2.點語法
            List<Student> stuList2 = stuCollection.AsQueryable().Where(s => s.age > 22).ToList();
            stuList1.ForEach(stu => Console.WriteLine($"姓名:{stu?.stuName},  年齡:{stu?.age}"));
            Console.WriteLine();

            //錶鏈接查詢,查詢各個學生的班級名
            Console.WriteLine("-------------錶鏈接,查詢學生的班級名----------------");
            //1.query語法
            var result1 = from stu in stuCollection.AsQueryable()
                          join cls in clsCollection.AsQueryable()
                            on stu.classNo equals cls.no
                          select new { stuno = stu.no, stu.stuName, cls.clsName };
            //2.點語法
            var result2 = stuCollection.AsQueryable().Join(
                            clsCollection.AsQueryable(),
                            stu => stu.classNo,
                            cls => cls.no,
                            (stu, cls) => new { stuno = stu.no, stu.stuName, cls.clsName }
                         );
            //遍歷結果
            foreach (var item in result1)
            {
                Console.WriteLine($"學號:{item.stuno}, 姓名:{item.stuName}, 班級:{item.clsName}");
            }

            Console.ReadKey();
        }
        /// <summary>
        /// 學生類
        /// </summary
        public class Student
        {
            public int no { get; set; }//學號
            public string stuName { get; set; }//姓名
            public int age { get; set; }//年齡
            public int classNo { get; set; }//班級編號
            [BsonExtraElements]
            public BsonDocument others { get; set; }
        }
        /// <summary>
        /// 班級類
        /// </summary>
        public class Classx
        {
            public int no { get; set; }//班級編號
            public string clsName { get; set; }//班級名
            [BsonExtraElements]
            public BsonDocument others { get; set; }
        }
    }
}

執行結果以下:

相關文章
相關標籤/搜索