如何为方法 MongoDB.Bson.Serialization.BsonSerializer.Deserialize 自定义映射字段名称或类型
Posted
技术标签:
【中文标题】如何为方法 MongoDB.Bson.Serialization.BsonSerializer.Deserialize 自定义映射字段名称或类型【英文标题】:How to custom mapping fields name or type for method MongoDB.Bson.Serialization.BsonSerializer.Deserialize 【发布时间】:2019-06-26 15:27:22 【问题描述】:我使用 MongoDB.Bson.Serialization.BsonSerializer.Deserialize() 方法将 MongoDB.Bson.BsonDocument 反序列化为 MyType。但该方法总是遇到 System.FormatException,因为 MyType 中的字段与 BsonDocument 中的字段不是 100% 匹配。
我尝试将复杂的 json 对象(我们称为 mobj)从 MongoDB(查询结果)转换为 C# 对象(我们称为 csobj),以便我可以处理数据。我使用的 csobj 中的默认数据类型是字符串。但是 mobj 太复杂了,我们对它的架构了解较少。
一旦在mobj中遇到BinData(0,"")、BinData(1,"")、BinData(2,"")、ISODate("")等数据类型,就有可能发生System.FormatException。
一旦 mobj 中有额外的新字段,可能会发生 System.FormatException。
一旦字段名称中有空格,例如“第一页”:“XXXX”,可能会发生 System.FormatException,我直到现在才知道如何解决。
var client = new MongoClient("mongodb://xxxxxx");
var database = client.GetDatabase("xxxxxxxxxx");
var collection = database.GetCollection<BsonDocument>("xxxxxxxxxx");
var results = await collection.Aggregate<BsonDocument>(filterBsonDocumentArray).ToListAsync();
foreach (var doc in results)
var model = MongoDB.Bson.Serialization.BsonSerializer.Deserialize<MyType>(doc); // always meet exception here
异常示例:
(mongodb 数据类型无法与字符串映射)
System.FormatException:反序列化 MongoQueryDemo.MyType 类的 Id 属性时出错:无法从 BsonType 'Binary' 反序列化 'String'。 ---> System.FormatException: 无法从 BsonType 'Binary' 反序列化 'String'。
(mongo中的_id在C#对象auto中找不到UserId)
System.FormatException:元素“_id”与 MongoQueryDemo.MyType 类的任何字段或属性都不匹配。
我的问题在这里列出:
有没有办法告诉Deserializer,请不区分大小写;
有没有办法自定义mobj到csobj的字段名映射,比如define "_id" --> UserId, "Ip Addr" --> "IpAddr";
有没有办法自定义数据类型,让数据类型BinData(0,""), BinData(1,""), BinData(2,""), ISODate("") 都可以在没有 System.FormatException 的情况下转换为字符串;
是否有任何方法可以将整个复杂的子对象映射到 C# 字符串,而不管其字段?由于它在模式较少的 mongodb 中是动态的,因此我无法在子对象中预定义任何未知字段。
【问题讨论】:
如果整个表的模式较少,为什么还要首先反序列化呢?将其用作BsonDocument
,您可以像.GetValue("<insert column name here>")
一样读取它,或使用database.GetCollectino<dynamic>
。
您好,不是全部,而是部分。我已经创建了 C# 对象,并且大多数 feilds 似乎无一例外地反序列化,并且有时它可以正常工作,除了需要获取一些动态子对象。
【参考方案1】:
此属性会将字段名称从 mobj 映射到 csojo `[BsonElement(@"52WeekChange")]
【讨论】:
欢迎来到 SO。可以举个例子说明如何使用属性?【参考方案2】:您有几个选项,正在探索here, in the docs。 (以下示例来自那里。)
您可以使用ClassMap
:
BsonClassMap.RegisterClassMap<MyClass>(cm =>
cm.MapProperty(c => c.SomeProperty);
cm.MapProperty(c => c.AnotherProperty);
);
如果你喜欢在你的 c# 类型声明中定义映射,你可以使用属性。
BsonContructor 可用于在对象构造期间映射属性:
public class Person
public string FirstName get; set;
public string LastName get; set;
// You can use this on one or more overloads as well:
[BsonConstructor]
public Person(string firstName, string lastName)
FirstName = firstName;
LastName = lastName;
BsonElement 是属性级解决方案:
public class MyClass
// The first parameter ("sp") is an optional mongodb field name mapping.
[BsonElement("sp")]
public string SomeProperty get; set;
【讨论】:
以上是关于如何为方法 MongoDB.Bson.Serialization.BsonSerializer.Deserialize 自定义映射字段名称或类型的主要内容,如果未能解决你的问题,请参考以下文章
如何为 Product* getProductFromID(std::string) 编写方法定义;