Có một vài điều đang diễn ra. Vấn đề chính là bạn phải sử dụng dữ liệu đầu vào bất kể loại nào hoặc quá trình deserialization không đồng bộ. Tôi đã thử nghiệm kịch bản của bạn khi viết một trình tuần tự tùy chỉnh có tên ZipCodeSerializer xử lý null và ghi ZipCodes dưới dạng chuỗi, nhưng chấp nhận chuỗi hoặc int trên đầu vào và chuyển đổi int thành chuỗi.
Tôi đã sử dụng lớp này để kiểm tra:
public class Address
{
public ObjectId Id;
public string ZipCode;
}
Và đây là bộ nối tiếp tùy chỉnh mà tôi đã viết:
public class ZipCodeSerializer : BsonBaseSerializer
{
public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
{
var bsonType = bsonReader.CurrentBsonType;
switch (bsonType)
{
case BsonType.Null:
bsonReader.ReadNull();
return null;
case BsonType.String:
return bsonReader.ReadString();
case BsonType.Int32:
return bsonReader.ReadInt32().ToString();
default:
var message = string.Format("ZipCodeSerializer expects to find a String or an Int32, not a {0}.", bsonType);
throw new BsonSerializationException(message);
}
}
public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
{
if (value == null)
{
bsonWriter.WriteNull();
}
else
{
bsonWriter.WriteString((string)value);
}
}
}
Bạn phải đảm bảo rằng bộ nối tiếp tùy chỉnh đã được kết nối, bạn có thể làm như sau:
BsonClassMap.RegisterClassMap<Address>(cm =>
{
cm.AutoMap();
cm.GetMemberMap(a => a.ZipCode).SetSerializer(new ZipCodeSerializer());
});
Vì vậy, bây giờ trường ZipCode của lớp Địa chỉ sẽ được xử lý bởi bộ nối tiếp tùy chỉnh.
Tôi đã tạo một số dữ liệu thử nghiệm bằng BsonDocument để dễ dàng buộc các phiên bản dữ liệu được lưu trữ cụ thể trong bộ sưu tập thử nghiệm của mình:
collection.Drop();
collection.Insert(new BsonDocument());
collection.Insert(new BsonDocument("ZipCode", BsonNull.Value));
collection.Insert(new BsonDocument("ZipCode", "12345"));
collection.Insert(new BsonDocument("ZipCode", 56789));
Đây là giao diện của các tài liệu khi sử dụng mongo shell:
> db.test.find()
{ "_id" : ObjectId("4f871374e447ad238040e346") }
{ "_id" : ObjectId("4f871374e447ad238040e347"), "ZipCode" : null }
{ "_id" : ObjectId("4f871374e447ad238040e348"), "ZipCode" : "12345" }
{ "_id" : ObjectId("4f871374e447ad238040e349"), "ZipCode" : 56789 }
>
vì vậy chúng tôi thấy rằng một số ZipCodes là chuỗi và một số là int (cũng có một null được đưa vào).
Và đây là mã thử nghiệm của tôi:
foreach (var document in collection.FindAll())
{
Console.WriteLine(document.ToJson());
}
Và kết quả của việc chạy mã kiểm tra là:
{ "_id" : ObjectId("4f871374e447ad238040e346"), "ZipCode" : null }
{ "_id" : ObjectId("4f871374e447ad238040e347"), "ZipCode" : null }
{ "_id" : ObjectId("4f871374e447ad238040e348"), "ZipCode" : "12345" }
{ "_id" : ObjectId("4f871374e447ad238040e349"), "ZipCode" : "56789" }
Press Enter to continue
Lưu ý rằng mã vùng từng là int trong cơ sở dữ liệu bây giờ là một chuỗi.
Mã nguồn đầy đủ của chương trình thử nghiệm của tôi hiện có tại: