.net Core MongoDB用法演示


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

0.准備測試數據

使用js 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,這里就不再演示了。

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

1.簡單查詢(Find、Filter)

 查找name=“吳九"的記錄

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);

查詢結果如下:

 

如果我們想查詢所有的記錄,可以設置過濾器為空,代碼為: var docs = collection.Find(filter.Empty).ToList(); 

2.AND查詢

查詢年齡大於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<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; }
        }
    }
}

執行結果如下:




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM