设为首页 收藏本站
查看: 766|回复: 0

[经验分享] MongoDB学习(翻译5)

[复制链接]

尚未签到

发表于 2015-7-6 10:35:40 | 显示全部楼层 |阅读模式
C#驱动序列化文档对象

介绍

本文档基于C#官方驱动1.8版本。

本节C#驱动教程谈论C#类到BSON对象的序列化和反序列化。序列化是映射一个对象到可保存到MongoDB库中BSON对象的过程,反序列化由BSON文档重建对象的逆过程。因此,序列化过程通常被称为“对象映射”

序列化使用BSON库处理。BSON库拥有一个可扩展的序列化结构,所以你可以控制你的序列化方式。BSON库提供的默认的序列化其可以满足你大部分的需求,如果你需要特殊处理,你可以对其进行扩展。

默认序列化器通过“类映射”来处理。类映射是定义类和BSON文档对象间映射的一种结构,它包含一系列参与序列化的字段或属性并且为每一个定义了所需的序列化参数(例如,BSON元素名,代表选项等)。

默认的序列化器也内建了对.NET数据类型(原始类型、数组、集合、字典等)的支持。

序列化一个类对象之前,该类映射必须存在,可以手动创建类映射也可以简单的通过自动映射来创建。你可以在类自动映射的过程中通过使用序列化相关特性或者初始化代码的方式施加一些控制。


创建类映射

在你的初始化代码中创建类映射:




BsonClassMap.RegisterClassMap();
  
在此MyClass 会被自动映射或者注册,当然你可以让你的类通过序列化器自动映射。

如果你想控制创建的类映射,你可以在一个lambda表达式中提供您自己的初始化代码:





BsonClassMap.RegisterClassMap {
cm.MapProperty(c => c.SomeProperty);
cm.MapProperty(c => c.AnotherProperty);
});
  
当lambda表达式执行“CM”(简称类映射),参数传递一个空类映射供您填充。在本例子中两个属性通过调用MapProperty 方法被添加进去,传进MapProperty 的参数是它们本身。使用lambda表达式,而不是仅仅使用一个字符串参数的属性名称的优点是IntelliSense和编译时检查,确保你正确的拼写属性名称。

另外,也可以使用自动映射,然后覆写一些结果。稍后我们将会看到这方面的例子。

注意类映射必须只能被注册一次(如果你试着多次注册同一个类,会抛出异常)。

通常情况,你可以在只执行一次的代码路径中调用RegisterClassMapMain 方法,Application_Start 事件等),如果你在执行次数多于一次的代码路径中调用RegisterClassMap 方法,你也可以通过调用IsClassMapRegistered 来检查该类是否被注册过:




if (!BsonClassMap.IsClassMapRegistered(typeof(MyClass))) {
// 为MyClass注册类映射

}
  
Creator Maps

默认情况下,类必定包括一个无参的构造函数来用于类的实例化,然后配置一个具有和映射属性相关的参数的构造函数是可以的,有两种方法可以实现:

使用一个表达式,你可以按照下面方式通过驱动使用一个creator map




public class Person
{
public string FirstName { get; private set; }
public string LastName { get; private set; }

public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
}

BsonClassMap.RegisterClassMap(cm =>
{
cm.AutoMap();
cm.MapCreator(p => new Person(p.FirstName, p.LastName));
});
  
解析表达式树使构造函数第一个参数和FirstName 相关,使构造函数第二个参数和LastName 属性相关。还有其他更复杂的方式处理这种情况,当需要时,可以研究探索。

通过特性:




public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }

[BsonConstructor]
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
}
  
当不止一个构造函数是,我们通过“满足大多数参数”这一策略来确定哪个是最好的匹配,例如:




public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime? BirthDate { get; set; }

[BsonConstructor]
public Person(string firstName, string lastName)
{
// snip...

}

[BsonConstructor]
public Person(string firstName, string lastName, DateTime birthDate)
{
// snip...

}
}
  
如果数据库中文档对象有一个BirthDate字段,我们会选择使用包含3个参数的构造函数,因为它更具体。

除了上面代码和属性的形式,映射一创建者可以通过约定(约束)来处理。

约定(约束)

自动进行类映射有许多需要考虑的方面,例如

. 例如



  • 哪个字段或属性应该被序列化
  • 哪个字段或属性是ID列
  • 什么元素名称可以被用在BSON文档中
  • 如果是多态,怎么确定使用哪个
  • 如果我们无法识别一个BSON文档中包含的元素会如何
  • 字段或属性是否有一个默认值
  • 默认值应该被序列化还是被忽略
  • null 值应该被序列化还是被忽略

这些问题的答案就代表一组约定。对于每一个约定都有一个默认的惯例,它是最有可能被您使用的一个,在必要时也可以重新个别约定(甚至写你自己的)。

如果你想使用和默认约定不同的自己的约定,可以很简单的创建一个ConventionPack 的实例,添加你想使用的约定进去,然后注册(换句话说,当你使用具体约定的时候通知序列化器)。例如:




var myConventions = new ConventionPack();
pack.Add(new CamelCaseElementNameConvention());

ConventionRegistry.Register(
"My Custom Conventions",
pack,
t => t.FullName.StartsWith("MyNamespace."));
  
第三个参数是用来定义何时使用这个约定包的过滤器方法。在这种情况下,也就是指如果任何类的全名以MyNamespace开头的话应该使用myConventions约定。

由上面我们已经了解到,除了预定的约定(约束),你可以自定义自己的约定(约束)。有4个可以让我们创建和注册自定义约定的类,运行在不同(阶段)级别。



  • 类(阶段)级别: IClassMapConvention

运行针对类映射阶段.



  • 方法(成员)级别(阶段): IMemberMapConvention

运行针对在IClassMapConvention 阶段发现映射的每名成员



  • Creator阶段: ICreatorMapConvention

运行针对在IClassMapConvention 阶段发现映射的CreatorMap




  • 后期处理阶段: IPostProcessingConvention

运行针对类映射阶段.


约定在他们注册的每个阶段顺序运行,默认的约定会先注册,这就允许任何用户注册的约定覆盖掉默认的约定。所以某些值可能得到应用和覆写,这就要求用户确保注册顺序的正确性。

注意:


如果一个IPostProcessingConvention 的自定义实现的注册早于一个IClassMapConvention的自定义实现,那么IClassMapConvention 先运行,因为它是运行类阶段是早于后处理阶段的。


待续。。。。

下篇介绍:

Field or Property Level Serialization Options

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-83748-1-1.html 上篇帖子: Mongodb使用总结 下篇帖子: MongoDB:安装步骤
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表