如何使用MongoDB C#serializer序列化值类型?
Mongodb C#驱动程序不会序列化结构/值类型。如何做到这一点?您可以使用以下代码创建自定义序列化程序来处理结构:如何使用MongoDB C#serializer序列化值类型?,c#,mongodb,serialization,struct,value-type,C#,Mongodb,Serialization,Struct,Value Type,Mongodb C#驱动程序不会序列化结构/值类型。如何做到这一点?您可以使用以下代码创建自定义序列化程序来处理结构: public class StructBsonSerializer : IBsonSerializer { public void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { va
public class StructBsonSerializer : IBsonSerializer
{
public void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
{
var fields = nominalType.GetFields(BindingFlags.Instance | BindingFlags.Public);
var propsAll = nominalType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
var props = new List<PropertyInfo>();
foreach (var prop in propsAll)
{
if (prop.CanWrite)
{
props.Add(prop);
}
}
bsonWriter.WriteStartDocument();
foreach (var field in fields)
{
bsonWriter.WriteName(field.Name);
BsonSerializer.Serialize(bsonWriter, field.FieldType, field.GetValue(value));
}
foreach (var prop in props)
{
bsonWriter.WriteName(prop.Name);
BsonSerializer.Serialize(bsonWriter, prop.PropertyType, prop.GetValue(value, null));
}
bsonWriter.WriteEndDocument();
}
public object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
{
var obj = Activator.CreateInstance(actualType);
bsonReader.ReadStartDocument();
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
{
var name = bsonReader.ReadName();
var field = actualType.GetField(name);
if (field != null)
{
var value = BsonSerializer.Deserialize(bsonReader, field.FieldType);
field.SetValue(obj, value);
}
var prop = actualType.GetProperty(name);
if (prop != null)
{
var value = BsonSerializer.Deserialize(bsonReader, prop.PropertyType);
prop.SetValue(obj, value, null);
}
}
bsonReader.ReadEndDocument();
return obj;
}
public object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
{
return Deserialize(bsonReader, nominalType, nominalType, options);
}
public bool GetDocumentId(object document, out object id, out Type idNominalType, out IIdGenerator idGenerator)
{
throw new NotImplementedException();
}
public void SetDocumentId(object document, object id)
{
throw new NotImplementedException();
}
}
基于上面的代码,我设法使其适应Mongo驱动程序版本2.2.3
public class BasicStructSerializer<T> : StructSerializerBase<T> where T: struct
{
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, T value)
{
var nominalType = args.NominalType;
var fields = nominalType.GetFields(BindingFlags.Instance | BindingFlags.Public);
var propsAll = nominalType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
var props = new List<PropertyInfo>();
foreach (var prop in propsAll)
{
if (prop.CanWrite)
{
props.Add(prop);
}
}
var bsonWriter = context.Writer;
bsonWriter.WriteStartDocument();
foreach (var field in fields)
{
bsonWriter.WriteName(field.Name);
BsonSerializer.Serialize(bsonWriter, field.FieldType, field.GetValue(value));
}
foreach (var prop in props)
{
bsonWriter.WriteName(prop.Name);
BsonSerializer.Serialize(bsonWriter, prop.PropertyType, prop.GetValue(value, null));
}
bsonWriter.WriteEndDocument();
}
public override T Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
//boxing is required for SetValue to work
var obj = (object)(new T());
var actualType = args.NominalType;
var bsonReader = context.Reader;
bsonReader.ReadStartDocument();
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
{
var name = bsonReader.ReadName();
var field = actualType.GetField(name);
if (field != null)
{
var value = BsonSerializer.Deserialize(bsonReader, field.FieldType);
field.SetValue(obj, value);
}
var prop = actualType.GetProperty(name);
if (prop != null)
{
var value = BsonSerializer.Deserialize(bsonReader, prop.PropertyType);
prop.SetValue(obj, value, null);
}
}
bsonReader.ReadEndDocument();
return (T)obj;
}
}
公共类BasicStructSerializer:StructSerializerBase其中T:struct
{
public override void Serialize(BsonSerializationContext,BsonSerializationArgs参数,T值)
{
var nominalType=args.nominalType;
var fields=nominalType.GetFields(BindingFlags.Instance | BindingFlags.Public);
var propsAll=nominalType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
var props=新列表();
foreach(propsAll中的var prop)
{
如果(道具可写)
{
道具。添加(道具);
}
}
var bsonWriter=context.Writer;
bsonWriter.WriteStartDocument();
foreach(字段中的变量字段)
{
bsonWriter.WriteName(字段名);
序列化(bsonWriter,field.FieldType,field.GetValue(value));
}
foreach(道具中的var道具)
{
bsonWriter.WriteName(项目名称);
序列化(bsonWriter,prop.PropertyType,prop.GetValue(value,null));
}
bsonWriter.WriteEndDocument();
}
公共重写T反序列化(BsonDeserializationContext,BsonDeserializationArgs args args)
{
//要使SetValue工作,需要装箱
var obj=(object)(新的T());
var actualType=args.NominalType;
var bsonReader=context.Reader;
bsonReader.ReadStartDocument();
while(bsonReader.ReadBsonType()!=BsonType.EndOfDocument)
{
var name=bsonReader.ReadName();
var field=actualType.GetField(名称);
如果(字段!=null)
{
var value=BsonSerializer.Deserialize(bsonReader,field.FieldType);
字段设置值(obj,值);
}
var prop=actualType.GetProperty(名称);
如果(prop!=null)
{
var value=BsonSerializer.Deserialize(bsonReader,prop.PropertyType);
属性设置值(对象,值,空);
}
}
bsonReader.ReadEndDocument();
返回(T)obj;
}
}
用法:
cm.GetMemberMap(c => c.SomeMemberName).SetSerializer(new BasicStructSerializer<SomeMemberType>());
cm.GetMemberMap(c=>c.SomeMemberName).SetSerializer(新的BasicStructSerializer());
这张照片拍得不错,不过没有找到更好的名字匹配。也就是说,如果您选择应用驼峰式套管惯例,则此代码将不起作用。我将尝试修补它…我像使用BsonSerializer.RegisterSerializer(新的BasicStructSerializer())一样使用它代码>
cm.GetMemberMap(c => c.SomeMemberName).SetSerializer(new BasicStructSerializer<SomeMemberType>());