猿教程 Logo

.Net连接MongoDb:.NET驱动程序中的对象序列化(续)

介绍

在上一篇文章中,我们开始研究MongoDb .NET驱动程序中的对象序列化。 序列化属性,像BsonElement,帮助我们声明了我们的C#对象和相应的文档之间的映射。 我们可以将JSON属性映射到C#属性,声明属性的类型与其JSON对应方式不同,等等。

在这篇文章中,我们将介绍MongoDb .NET驱动程序中更多的数据序列化示例。 一个很好的文档位于MongoDb页面专用于此主题。 它通过更高级的案例,如超类型和子类型,自定义序列化和自定义属性。

更多MongoDb序列化选项

有时您可能希望偏离标准序列化机制:您可以忽略某些属性或定义不同的属性名称。 MongoDb中的序列化属性将在此帮助您。 它们类似于.NET序列化中的DataMember,IgnoreMember等属性。 例子:

忽略元素

忽略一个属性使用BsonIgnore:

public class Customer
{
	public string Name { get; set; }
	public string Address { get; set; }
	IEnumerable<string> Telephones { get; set; }
	[BsonIgnore]
	public string PublicPage { get; set; }
}

PublicPage属性将不会在BSON文档中序列化。

忽略NULL值

public class Customer
{		
	public string Name { get; set; }
	[BsonIgnoreIfNull]
	public string Address { get; set; }
}

序列化专用字段

我们已经看到了BsonElement属性。 它有另一个目的。 默认情况下,私有字段不会被序列化。 您可以使用空的BsonElement将其包含在序列化中:

public class Customer
{		
	public string Name { get; set; }
	public string Address { get; set; }
	IEnumerable<string> Telephones { get; set; }
	[BsonElement]
	private WebPage PublicPage { get; set; }
}

不同的数据类型

声明在BSON中如何表示属性,即使用BsonRepresentation属性在哪种类型下表示:

public class Customer
{
	[BsonRepresentation(MongoDB.Bson.BsonType.Double)]
	public decimal TotalOrders { get; set; }
}

.NET十进制类型在BSON中没有等效项,它被视为使排序和比较效率低下的字符串。 最好将其投射到足够接近的BSON双倍。

ID字段

我们之前看到,唯一的ID字段默认称为“_id”,类型为ObjectId。 您可以使用BsonId属性声明不同的ID字段:

public class Customer
{
	[BsonId]
	public int CustomerId { get; set; }
}

该ID仍将在文档中序列化为“_id”,但您可以在POCO中将其称为“CustomerId”。

日期

日期总是与所有时区和格式不同的野兽。 当日期字段被序列化时,MongoDb会将所有本地日期自动翻译成UTC。 但是,当日期被反序列化时,它可能会产生问题。 默认情况下,您将获得UTC日期,而您可能希望本地日期。 我认为只有在您的域中使用UTC并且仅转换视图的日期才能始终是明智的,但您可以使用BsonDateTimeOptions属性来覆盖默认行为:

public class Customer
{
	[BsonDateTimeOptions(Kind = DateTimeKind.Local)]
	public DateTime CustomerSince { get; set; }
}

这样,存储在文档中的UTC日期将被转换为计算机的本地时区。

如果您只想存储日期的“日期”部分,即没有小时:分钟:秒位,则使用BsonDateTimeOptions的DateOnly参数:

public class Customer
{
	[BsonDateTimeOptions(Kind = DateTimeKind.Local, DateOnly = true)]		
	public DateTime CustomerSince { get; set; }
}

还有很多其他序列化案例,我们在这里没有介绍。 目标主要是让您了解基本的数据序列化选项。 有关更多详细信息,请参阅上面引用的MongoDb文档页面。 对于更定制的序列化,您可以阅读此页面。

邮编集合

我们来扩展ModelContext类和zipcodes集合上的一个句柄。 邮政编码集合绝对比餐馆集合简单。 将以下类添加到Repository文件夹中:

using MongoDB.Bson.Serialization.Attributes;
using Newtonsoft.Json;

namespace MongoDbDotNet.Repository
{
	[BsonIgnoreExtraElements]
	public class ZipCodeDb
	{
		[BsonId]
		[BsonElement(elementName: "_id")]
		public string Id { get; set; }
		[BsonElement(elementName: "city")]
		public string City { get; set; }
		[BsonElement(elementName: "loc")]
		public double[] Coordinates { get; set; }
		[BsonElement(elementName: "pop")]
		public int Population { get; set; }
		[BsonElement(elementName: "state")]
		public string State { get; set; }

		public override string ToString()
		{
			return JsonConvert.SerializeObject(this, Formatting.Indented);
		}
	}
}

可以使用以下属性扩展ModelContext类:

public IMongoCollection<ZipCodeDb> ZipCodes
{
	get { return Database.GetCollection<ZipCodeDb>(ConfigurationRepository.GetConfigurationValue("ZipCodesCollectionName", "¨zipcodes")); }
}

我们来从Main方法来测试:

ZipCodeDb firstInMassachusetts = modelContext.ZipCodes.FindSync(z => z.State == "MA").FirstOrDefault();
Console.WriteLine(firstInMassachusetts);

上面的示例给出了我们之前看到的不同样式的查询的预览。 前面的例子基于从静态Builders类构建的过滤器。 上面的例子演示了一个LINQ查询。 我们想在马萨诸塞州找到第一间餐厅。 这是我在控制台窗口中所得到的:

{
  "Id": "01001",
  "City": "AGAWAM",
  "Coordinates": [
    -72.622739,
    42.070206
  ],
  "Population": 15338,
  "State": "MA"
}

在下一篇文章中,我们将介绍如何在.NET驱动程序中查询数据。


版权声明:本站所有教程均为本站原创或翻译,转载请注明出处,请尊重他人劳动果实。请记住本站地址:www.yuanjiaocheng.net (猿教程) 作者:卿文刚
本文标题: C#环境
本文地址:http://www.yuanjiaocheng.net/CsharpMongo/15.html