亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#中如何將MongoDB->RunCommand結果映射到業務類的方法總結

2019-10-29 21:06:04
字體:
來源:轉載
供稿:網友

前言

一直沒實際用過MongoDB,最近有個項目中用了用,踩了一些坑。這篇文章會介紹將MongoDB->RunCommand結果映射到業務類時碰到的問題,以及對各種方法的探索。

Collection中的數據是這樣的:

mongodb,runcommand,結果集映射,command

使用find命令查詢數據:

db.runCommand({"find":"test", limit:2, sort:{AddTime:-1}})

查詢返回的數據結構是這樣的,需要的數據在firstBatch中:

{ "cursor" : { "firstBatch" : [   {  "_id" : ObjectId("5ad0042944fd3929db6b869f"),  "Name" : "李四",  "AddTime" : ISODate("2018-04-12T01:13:18.965Z")  },   {  "_id" : ObjectId("5ad003e844fd3929db6b869e"),  "Name" : "張三",  "AddTime" : ISODate("2018-04-02T01:11:18.965Z")  } ], "id" : NumberLong(0), "ns" : "test.test" }, "ok" : 1.0}

下面將在C#中運行find命令來執行查詢,并將結果映射到自定義的PersonInfo類。

 private class PersonInfo {  public string Id { get; set; }  public string Name { get; set; }  public DateTime AddTime { get; set; } }

需要注意PersonInfo中的屬性Id和Document中的名稱_id有些不一樣,需要進行映射。因為不同的反序列化方法,采用的方式也會不同,所以下面會有相關介紹。

使用Json.NET

因為Json.NET用的比較多,基本思路就是用它來反序列化Bson,但是Json和Bson是不同的,不能用JsonConvert。

不過Json.NET提供了一個新的包Newtonsoft.Json.Bson來解析Bson數據,并且提供了一個例子。

https://www.newtonsoft.com/json/help/html/DeserializeFromBson.htm

這個例子有點過時了,里邊用的BsonReader我已替換為BsonDataReader。

byte[] data = Convert.FromBase64String("MQAAAAJOYW1lAA8AAABNb3ZpZSBQcmVtaWVyZQAJU3RhcnREYXRlAMDgKWE8AQAAAA==");MemoryStream ms = new MemoryStream(data);using (BsonDataReader reader = new BsonDataReader(ms)){ JsonSerializer serializer = new JsonSerializer();  Event e = serializer.Deserialize<Event>(reader);  Console.WriteLine(e.Name); // Movie Premiere}

看樣子有個byte數組就可以了,然后再看BsonDocument正好有個方法ToBson,獲取到的就是byte[]。

思路:先將RunCommand的結果映射為BsonDocument,然后查找到firstBatch,然后將其ToBson,然后使用Newtonsoft.Json.Bson反序列化。

一切看起來很easy!

馬上碼起來:

  var findCommand = BsonDocument.Parse("{/"find/":/"test/", limit:2, sort:{AddTime:-1}}");  var findResult = database.RunCommand<BsonDocument>(findCommand)  .GetElement("cursor").Value.ToBsonDocument()  .GetElement("firstBatch").ToBsonDocument()  .ToBson();  var personList = DeserializeBson<PersonList>(findResult);

數組不能是Bson的根元素,所以這里定義了一個PersonList類:

 private class PersonList {  public string Name { get; set; }  [JsonProperty(PropertyName = "Value")]  public PersonInfo[] List { get; set; } }

需要注意的是上邊代碼中 GetElement(“firstBatch”).ToBsonDocument() 返回的數據格式是這樣的:

mongodb,runcommand,結果集映射,command

這里用了JsonProperty將Value映射為List。

還有Person類中的屬性名稱和document中的也有不同,也需要映射:

 private class PersonInfo {  [JsonProperty(PropertyName = "_id")]  [JsonConverter(typeof(ObjectIdConverter))]  public string Id { get; set; }  public string Name { get; set; }  public DateTime AddTime { get; set; } }

這里還用了一個 JsonConverter(typeof(ObjectIdConverter)) ,因為ObjectId不能直接轉換為string,所以定義了一個ObjectIdConverter類:

 public class ObjectIdConverter : JsonConverter {  public override bool CanConvert(Type objectType)  {   return objectType == typeof(ObjectId);  }   public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)  {   if (reader.Value != null)   {    var value = (byte[])reader.Value;     var result = BitConverter.ToString(value).Replace("-", string.Empty).ToLowerInvariant();     return result;   }    return string.Empty;  }   public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)  {   throw new NotImplementedException();  } }

還有一個重要的方法,反序列化:

  public static T DeserializeBson<T>(byte[] data)  {   MemoryStream ms = new MemoryStream(data);   using (BsonDataReader reader = new BsonDataReader(ms, false, DateTimeKind.Local))   {    JsonSerializer serializer = new JsonSerializer();     T e = serializer.Deserialize<T>(reader);    return e;   }  }

現在運行程序看看吧:

mongodb,runcommand,結果集映射,command

但是感覺好復雜,過了一彎又一彎。

使用MongoDB .NET Driver內置

話說這么常用的功能,SDK應該內置了才對,何必舍近求遠,。

既然RunCommand可以傳遞一個類型,那么SDK應該是支持反序列化自定義類型的。

嘗試根據返回的結果定義一個新的類:

  [BsonIgnoreExtraElements]  private class FindCommandResult  {   [BsonElement("cursor")]   public ResultCursor Cursor { get; set; }  }   [BsonIgnoreExtraElements]  private class ResultCursor  {   [BsonElement("firstBatch")]   public PersonInfo[] Batch { get; set; }  }   private class PersonInfo  {   [BsonId]   [BsonRepresentation(BsonType.ObjectId)]   public string Id { get; set; }   public string Name { get; set; }   public DateTime AddTime { get; set; }  }

BsonIgnoreExtraElements、BsonElement、BsonId、BsonRepresentation這些都是SDK內置的Attribute,相關作用大家應該能夠一目了然。

再看看查詢這塊的代碼:

   var findCommand = BsonDocument.Parse("{/"find/":/"test/", limit:1, sort:{AddTime:-1}}");   var findResult = database.RunCommand<FindCommandResult>(findCommand);

代碼跑起來:

mongodb,runcommand,結果集映射,command

這個方式相比Json.NET更直接,更簡單。

使用查找賦值的方式

為了反序列化,適應MongoDB,定義了一些沒有業務意義的類型,加了很多的屬性注解,感覺還不夠直接顯性。

也許只需要數據中的某幾個字段,或者根本就沒必要定義類型,只需要放到一個列表中。

又查看了BsonDocument的定義,發現可以在運行命令時先反序列化為BsonDocument,然后再根據返回的數據結構使用GetElement獲取相關字段的值。

代碼如下:

   var findCommand = BsonDocument.Parse("{/"find/":/"test/", limit:2, sort:{AddTime:-1}}");   var findResult = database.RunCommand<BsonDocument>(findCommand)    .GetElement("cursor").Value.ToBsonDocument()    .GetElement("firstBatch").Value.AsBsonArray.Select(d =>    {     var dbd = d.AsBsonDocument;     return new PersonInfo()     {      Id = dbd.GetElement("_id").Value.AsObjectId.ToString(),      AddTime = dbd.GetElement("AddTime").Value.ToLocalTime(),      Name = dbd.GetElement("Name").Value.ToString(),     };    }).ToList();

運行后直接返回List<PersonInfo> ,更貼近業務需求。

這是本文中最簡單的方式了。

如果做的更通用點,可以在這里通過反射自動實例化相關類型,不過這不如直接使用SDK內置的反序列化方式了。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久国产91| 97视频在线观看亚洲| 日韩成人xxxx| 日韩激情片免费| 亚洲性xxxx| 午夜精品在线视频| 色婷婷综合成人| 国产精品偷伦视频免费观看国产| 欧洲s码亚洲m码精品一区| 亚洲欧美精品在线| 国产成人一区二区三区电影| 操91在线视频| 日韩免费高清在线观看| 久久精品国产欧美亚洲人人爽| 亚洲欧美中文在线视频| 一区二区三区四区在线观看视频| 国产精品精品视频一区二区三区| 亚洲深夜福利网站| 正在播放亚洲1区| 成人免费淫片aa视频免费| 欧美成人午夜激情| 久久色精品视频| 亚洲区bt下载| 国产成人精品免高潮在线观看| 中文字幕国产精品| 日韩av影院在线观看| 在线视频国产日韩| 亚洲国产欧美自拍| 久久久久99精品久久久久| 国模极品一区二区三区| 欧美亚洲第一页| 亚洲性av网站| www.亚洲一区| 精品视频在线播放免| 欧美又大粗又爽又黄大片视频| 国产97在线|日韩| 成人国产精品av| 91久久久久久| 国产成人欧美在线观看| 欧美巨乳美女视频| 欧美极品在线播放| 日本欧美中文字幕| 日韩大片在线观看视频| 97国产精品人人爽人人做| 日韩视频中文字幕| 国产精品久久久久久久午夜| 国产精品香蕉国产| 在线中文字幕日韩| 亚洲免费成人av电影| 日韩综合中文字幕| 91在线无精精品一区二区| 亚洲人成亚洲人成在线观看| 91久久精品在线| 国产精品亚洲美女av网站| 成人av资源在线播放| 亚洲精品v天堂中文字幕| 亚洲va国产va天堂va久久| 成人av.网址在线网站| 亚洲日本欧美日韩高观看| 97视频在线播放| 亚洲精品www| 久久免费少妇高潮久久精品99| 97视频国产在线| 国产成人精品久久二区二区91| 亚洲2020天天堂在线观看| 日韩福利视频在线观看| 国产99久久精品一区二区永久免费| 国产综合久久久久| 亚洲精品国偷自产在线99热| 91美女片黄在线观| 在线丨暗呦小u女国产精品| 人人澡人人澡人人看欧美| 狠狠综合久久av一区二区小说| 国内久久久精品| 久久久国产精品亚洲一区| 欧美有码在线观看| 国产精品偷伦视频免费观看国产| 91久久国产综合久久91精品网站| 2020欧美日韩在线视频| 成人免费视频网址| 欧美日韩亚洲一区二| 欧美中文字幕在线视频| 成人网页在线免费观看| 久久中文久久字幕| 亚洲国产精品99| 丁香五六月婷婷久久激情| 久久精品成人欧美大片| 欧美贵妇videos办公室| 91精品国产综合久久久久久久久| 亚洲天堂网在线观看| 精品久久国产精品| 国产精品国模在线| 51ⅴ精品国产91久久久久久| 欧美xxxx18国产| 欧美裸身视频免费观看| 日韩av在线影视| 欧美极品第一页| 久久精品视频中文字幕| 中文字幕亚洲天堂| 亚洲精品自拍第一页| 韩国三级日本三级少妇99| 激情av一区二区| 国产欧美一区二区| 97热精品视频官网| 日本最新高清不卡中文字幕| 一道本无吗dⅴd在线播放一区| 亚洲精品日韩欧美| 日韩一区在线视频| 伊人激情综合网| 92看片淫黄大片欧美看国产片| 一个人www欧美| 久久精品一本久久99精品| 日韩欧美国产网站| 亚洲精品小视频在线观看| 久久久久亚洲精品| 亚洲大胆人体视频| 国产伦精品一区二区三区精品视频| 亚洲一品av免费观看| 亚洲精品xxxx| 国模精品视频一区二区| 国产97色在线| 成人444kkkk在线观看| 久久在线免费观看视频| 色悠悠久久久久| 色樱桃影院亚洲精品影院| 亚洲护士老师的毛茸茸最新章节| 久久精品国产成人精品| 国产91精品久久久| 中文字幕亚洲激情| 日本午夜精品理论片a级appf发布| 亚洲石原莉奈一区二区在线观看| 国产欧美精品日韩| 成人春色激情网| 国产欧美欧洲在线观看| 最新69国产成人精品视频免费| 91久久国产综合久久91精品网站| 国产欧美日韩综合精品| 17婷婷久久www| 亚洲精品www| 久久中文精品视频| 亚洲综合日韩中文字幕v在线| 狠狠色香婷婷久久亚洲精品| 日韩欧美成人精品| 欧美亚洲视频在线观看| 久久综合免费视频影院| 伊人久久久久久久久久久| 欧美性猛交xxxx乱大交3| 精品人伦一区二区三区蜜桃免费| 精品国产精品三级精品av网址| 欧美精品18videos性欧| 欧美夫妻性视频| 欧美日韩人人澡狠狠躁视频| 亚洲国产精品热久久| 萌白酱国产一区二区| 日韩精品久久久久| 国产精品免费视频xxxx| 色爱av美腿丝袜综合粉嫩av| 午夜精品久久久久久99热软件| 国产精品91久久| 久久精品青青大伊人av| 在线观看91久久久久久| 国产精品欧美一区二区| 欧美性视频精品| 狠狠色噜噜狠狠狠狠97|