C#驅動MongoDB的本質是將C#的操做代碼轉換爲mongo shell,驅動的API也比較簡單明瞭,方法名和js shell的方法名基本都保持一致,熟悉mongo shell後學習MongoDB的C#驅動是十分輕鬆的,直接看幾個demo吧。mongodb
使用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:'上海' } ])
安裝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
查找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
查詢年齡大於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));
查詢結果以下:
查詢年齡小於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));
查詢結果以下:
查詢包含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));
查詢結果以下:
查詢年齡小於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));
查詢結果以下:
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));
查詢結果:
修改符合過濾條件的第一條記錄,例子:將張三的年齡改爲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);
執行結果:
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:
刪除操做比較簡單,DeleteOne用於刪除符合過濾條件的第一條記錄,DeleteMany用於刪除全部符合過濾條件的記錄。
刪除名字爲張三的記錄
//鏈接數據庫 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));
執行結果以下,咱們看到張三的記錄已經被刪除了:
刪除全部年齡大於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歲的記錄都被刪除了:
有時候咱們要讓查詢的結果映射到咱們的實體類中去,實現這個需求也十分簡單,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; } }
執行結果以下:
上邊的例子僅僅用了基本的自動化映射,使用基本的自動化映射時:類和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中的哪一個字段,
還有一些其餘的屬性,具體能夠參考官方文檔。
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; } } } }
執行結果以下: