MongoDB.Driver是操做mongo數據庫的驅動,最近2.0如下版本已經從GitHub和Nuget中移除了,也就是說.NET Framework4.0再也不能從官方獲取到MongoDB的驅動了,其次MongoDB.Driver2.0開始API變動巨大,本文不適用MongoDB.Driver2.0如下版本,亦不適用.NET Framework4.5如下版本mongodb
要在.NET中使用MongoDB,就必須引用MongoDB的驅動,使用Nuget安裝MongoDB.Driver是最方便的,目前Nuget支持的MongoDB程序包有對.NET Framework4.5以上版本的依賴數據庫
安裝完成以後會在引用中新增三個MongoDB的程序集引用,其中MongoDB.Driver.Core在2.0版本如下是沒有的分佈式
先構建一個實體基類,由於Mongo要求每一個文檔都有惟一Id,默認爲ObjectId類型(根據時間Mac地址Pid算出來的,相似GUID,適用於分佈式),在這個基類中添加Id屬性ide
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> { } }
開始構建數據庫訪問類DbContextui
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); } } }
現有數據庫數據 文檔book 包含數據以下spa
開始構建與文檔對應的實體,mongo是文檔數據庫,對單詞得大小寫是敏感得,因此構建的實體的字段也應該是小寫的,有點不符合習慣3d
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; } } }
如今開始增刪查改操做,其中查找和刪除的filter參數有兩種形式,lambda和Definitioncode
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); } } }
由於我對book類的ToString方法進行了重寫,因此輸出結果以下blog
上面都是用的數據庫和實體字段名一致的狀況,若是不一致怎麼辦呢,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; } } }
將上面執行操做的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; } } }
如今一切正常了,顯示結果和以前的同樣就再也不貼圖了,有子文檔的數據操做與此相似,譬若有以下數據
構建實體以下
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; } }