這兩天在工作中被Mongo集合存儲給整得頭大,當然也是我的認知太淺,所以下面我來分享下我所遇到的這個問題希望有大佬能給出更好的解決方案,
1.需求:
存儲一個從前端接收未知數據類型的集合
例:
由於是未知的數據類型,所有我創建了一個IList<Object>集合
public class Demo { public String Name { get; set; } public List<Object> List { get; set; } }
2.問題
按照我們平常的想法我們只要將數據從api接收到並且進行存儲即可,那么事實真是如此嗎,下面我們來進行一個簡單的測試
首先創建api
[RoutePrefix("Home")] public class HomeController : ApiController { public HomeController() { } //連接地址 private static string conn = "mongodb://192.168.11.51:40000"; //數據庫名稱 private static string dbName = "yan"; //集合名稱 private static string colName = "Demo"; static MongoClient client = new MongoClient(conn); //獲取指定數據庫 static IMongoDatabase db = client.GetDatabase(dbName); //獲取指定集合 BsonDocument數據庫文檔對象 static IMongoCollection<Demo> coll = db.GetCollection<Demo>(colName); [HttpPost] [Route("TestMongo")] public void TestMongo([FromBody] Demo demo) { coll.InsertOne(demo); } }
從上面可以看出我們在TestMongo只做了一件事,就是講接收到的數據進行存儲,
然后我們使用PostMan進行模擬請求測試
可以看到后台如願的獲取到了請求數據,那么存儲到Mongo中是什么呢,我們來看一下
可以看到這個集合存儲到Mongo中變成了一組我們幾乎看不懂的數據結構,那么這到底是怎么回事,下面我解析下我猜想的跟其解決方法。
3.解決方案
首先我們來獲取解析下從客戶端接收到的集合類型
我們可以看到集合中存儲的每一個類型是JObject類型,而展開這個類型時發現里面數據結構好像根本無法解析所以導致我們在存儲時並沒有按照我們所想的那樣進行存儲,那么該怎么進行解決呢,整了兩天整出了一個不算好的解決方案,
首先將集合改成IEnumberable<Object>類型(后面解釋其原因)
public class Demo { public String Name { get; set; } public IEnumerable<Object> List { get; set; } }
然后在api中做一些特殊處理
public void TestMongo([FromBody] Demo demo) { //1.將集合包裝成一個Object集合序列化 String strVal = JsonConvert.SerializeObject(new { data = demo.List }); //2.將序列化的字符串轉換成BsonDocument類型 BsonDocument doc = BsonDocument.Parse(strVal); //3.使用BsonDocument獲取被包裝的集合並轉換成BsonArray類型 var docArr = doc.GetValue("data").AsBsonArray; //4.獲取BsonArray的Values值並重寫賦給原集合引用 //【因為Values值是IEnumerable<BsonValue>類型,所以原集合必須是IEnumerable<Object>類型】 demo.List = doc.Values; coll.InsertOne(demo); }
上面代碼我們就可以將集合按照我們所想那樣進行存儲,我們來看一下效果
上面方案我感覺並不好,但是並沒有找到更好的方法,在此希望各位大佬能給出更好的解決方案