最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#中如何將MongoDB->RunCommand結(jié)果映射到業(yè)務(wù)類的方法總結(jié)

 更新時(shí)間:2018年04月21日 12:01:41   作者:波斯碼  
這篇文章主要給大家總結(jié)介紹了關(guān)于C#中如何將MongoDB->RunCommand結(jié)果映射到業(yè)務(wù)類的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。

前言

一直沒實(shí)際用過MongoDB,最近有個(gè)項(xiàng)目中用了用,踩了一些坑。這篇文章會介紹將MongoDB->RunCommand結(jié)果映射到業(yè)務(wù)類時(shí)碰到的問題,以及對各種方法的探索。

Collection中的數(shù)據(jù)是這樣的:

使用find命令查詢數(shù)據(jù):

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

查詢返回的數(shù)據(jù)結(jié)構(gòu)是這樣的,需要的數(shù)據(jù)在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#中運(yùn)行find命令來執(zhí)行查詢,并將結(jié)果映射到自定義的PersonInfo類。

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

需要注意PersonInfo中的屬性Id和Document中的名稱_id有些不一樣,需要進(jìn)行映射。因?yàn)椴煌姆葱蛄谢椒?,采用的方式也會不同,所以下面會有相關(guān)介紹。

使用Json.NET

因?yàn)镴son.NET用的比較多,基本思路就是用它來反序列化Bson,但是Json和Bson是不同的,不能用JsonConvert。

不過Json.NET提供了一個(gè)新的包Newtonsoft.Json.Bson來解析Bson數(shù)據(jù),并且提供了一個(gè)例子。

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

這個(gè)例子有點(diǎn)過時(shí)了,里邊用的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
}

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

思路:先將RunCommand的結(jié)果映射為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);

數(shù)組不能是Bson的根元素,所以這里定義了一個(gè)PersonList類:

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

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

這里用了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; }
 }

這里還用了一個(gè) JsonConverter(typeof(ObjectIdConverter)) ,因?yàn)镺bjectId不能直接轉(zhuǎn)換為string,所以定義了一個(gè)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();
  }
 }

還有一個(gè)重要的方法,反序列化:

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

現(xiàn)在運(yùn)行程序看看吧:

但是感覺好復(fù)雜,過了一彎又一彎。

使用MongoDB .NET Driver內(nèi)置

話說這么常用的功能,SDK應(yīng)該內(nèi)置了才對,何必舍近求遠(yuǎn),。

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

嘗試根據(jù)返回的結(jié)果定義一個(gè)新的類:

  [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內(nèi)置的Attribute,相關(guān)作用大家應(yīng)該能夠一目了然。

再看看查詢這塊的代碼:

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

代碼跑起來:

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

使用查找賦值的方式

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

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

又查看了BsonDocument的定義,發(fā)現(xiàn)可以在運(yùn)行命令時(shí)先反序列化為BsonDocument,然后再根據(jù)返回的數(shù)據(jù)結(jié)構(gòu)使用GetElement獲取相關(guān)字段的值。

代碼如下:

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

運(yùn)行后直接返回List<PersonInfo> ,更貼近業(yè)務(wù)需求。

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

如果做的更通用點(diǎn),可以在這里通過反射自動實(shí)例化相關(guān)類型,不過這不如直接使用SDK內(nèi)置的反序列化方式了。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • C# 設(shè)計(jì)模式系列教程-代理模式

    C# 設(shè)計(jì)模式系列教程-代理模式

    代理模式對客戶端來說,隱藏了真實(shí)對象的細(xì)節(jié)及復(fù)雜性,實(shí)現(xiàn)了客戶端(調(diào)用者)與真實(shí)對象的松耦合,提高了運(yùn)行速度。
    2016-06-06
  • c#多線程程序設(shè)計(jì)實(shí)例方法

    c#多線程程序設(shè)計(jì)實(shí)例方法

    在本篇文章里小編給大家分享了關(guān)于c#多線程程序設(shè)計(jì)實(shí)例步驟,需要的朋友們學(xué)習(xí)參考下。
    2019-02-02
  • C#程序加密工具.Net?Reactor詳細(xì)教程

    C#程序加密工具.Net?Reactor詳細(xì)教程

    .Net?Reacto加密工具是一款強(qiáng)大的?.NET?代碼保護(hù)和授權(quán)管理系統(tǒng),安全可靠、簡單易用,主要用來幫助開發(fā)人員保護(hù)他們的?.NET?軟件產(chǎn)品,本文給大家詳細(xì)介紹C#程序加密工具.Net?Reactor教程,感興趣的朋友一起看看吧
    2022-02-02
  • 在Framework 4.0中:找出新增的方法與新增的類(一)

    在Framework 4.0中:找出新增的方法與新增的類(一)

    經(jīng)??吹接型瑢W(xué)在討論Framework 4 的新特性,新方法,于是想寫個(gè)程序找出framework4.0中新增的方法和類
    2013-05-05
  • C#實(shí)現(xiàn)漢字轉(zhuǎn)區(qū)位碼的示例代碼

    C#實(shí)現(xiàn)漢字轉(zhuǎn)區(qū)位碼的示例代碼

    區(qū)位碼是一個(gè)4位的十進(jìn)制數(shù),每個(gè)區(qū)位碼都對應(yīng)著一個(gè)唯一的漢字,區(qū)位碼的前兩位叫做區(qū)碼,后兩位叫做位碼,下面我們就來看看如何使用C#實(shí)現(xiàn)漢字轉(zhuǎn)區(qū)位碼吧
    2024-01-01
  • C#對Word文檔的創(chuàng)建、插入表格、設(shè)置樣式等操作實(shí)例

    C#對Word文檔的創(chuàng)建、插入表格、設(shè)置樣式等操作實(shí)例

    今天小編就為大家分享一篇C#對Word文檔的創(chuàng)建、插入表格、設(shè)置樣式等操作實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • 關(guān)于C#中排序函數(shù)的總結(jié)

    關(guān)于C#中排序函數(shù)的總結(jié)

    下面小編就為大家?guī)硪黄P(guān)于C#中排序函數(shù)的總結(jié)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-05-05
  • C#生成本地配置文件的實(shí)現(xiàn)示例

    C#生成本地配置文件的實(shí)現(xiàn)示例

    本文將介紹如何使用C#語言生成本地配置文件,以便為應(yīng)用程序提供靈活的配置選項(xiàng),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • C#使用Task實(shí)現(xiàn)執(zhí)行并行任務(wù)的原理的示例詳解

    C#使用Task實(shí)現(xiàn)執(zhí)行并行任務(wù)的原理的示例詳解

    Task是一個(gè)表示異步操作的類,它提供了一種簡單、輕量級的方式來創(chuàng)建多線程應(yīng)用程序。本文就來和大家聊聊在C#中如何使用Task執(zhí)行并行任務(wù)吧
    2023-04-04
  • Winform中GridView分組排序功能實(shí)現(xiàn)方法

    Winform中GridView分組排序功能實(shí)現(xiàn)方法

    這篇文章主要介紹了Winform中GridView分組排序功能實(shí)現(xiàn)方法,以實(shí)例形式詳細(xì)說明了分組排序的實(shí)現(xiàn)方法,并附帶完整的DBHelp類代碼,是非常實(shí)用的技巧,需要的朋友可以參考下
    2014-11-11

最新評論

布拖县| 牙克石市| 麦盖提县| 获嘉县| 鞍山市| 广德县| 通州区| 宜春市| 桑日县| 图们市| 砀山县| 社会| 博野县| 东阿县| 海原县| 玉龙| 乌拉特中旗| 西宁市| 江阴市| 岢岚县| 荣成市| 普兰店市| 周至县| 木里| 繁昌县| 乌审旗| 天等县| 海南省| 陇南市| 汤原县| 和硕县| 溧阳市| 吴川市| 徐闻县| 宝应县| 睢宁县| 罗田县| 怀远县| 常州市| 临湘市| 尚义县|