[英]Using a custom serializer in MongoDB for a nested object interferes with filters using that object
我有如下定义的模型(我省略了与问题没有直接关系的部分):
public class AnObjectWithState {
public AbstractState State { get; private set; }
}
public abstract class AbstractState {
public State Representation { get; protected set; }
}
public enum State {
State1,
State2,
State3
}
和序列化程序代码:
public class AbstractStateSerializer : SerializerBase<AbstractState>
{
public override AbstractState Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) =>
StateFactory.CreateFor(base.Deserialize(context, args));
}
这段代码是我用来注册序列化程序的:
cm.MapField(c => c.State).SetSerializer(new AbstractStateSerializer());
现在,当我对我的 MongoDB 实例发出计数查询时,我收到一条错误消息:
System.InvalidOperationException:不支持转换({document}{State}.Representation,Int32)。
很明显,序列化程序是罪魁祸首,因为当我删除SetSerializer
调用时,一切正常。 您可能会说我在做的事情看起来很奇怪,但是请理解上面的AbstractState
实现是最小版本 - 实际上它有更多代码,并且需要以 MongoDB 无法运行的方式初始化代码。 我的目标是有一个干净的聚合 - 只包含业务逻辑而不是构造逻辑。 这就是为什么我宁愿有一些基础设施代码(如自定义序列化程序)来初始化 state object。 关于如何使其工作的任何想法?
成功的关键是实现IBsonDocumentSerializer
。 如果有人感兴趣,我的实现如下:
public class AbstractStateSerializer : SerializerBase<AbstractState>, IBsonDocumentSerializer
{
public override AbstractState Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
context.Reader.ReadStartDocument();
context.Reader.ReadBsonType();
context.Reader.SkipName();
var value = context.Reader.ReadInt32();
context.Reader.ReadEndDocument();
var state = // here I construct a graph of objects based on the above value variable
return state;
}
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, AbstractState value)
{
context.Writer.WriteStartDocument();
context.Writer.WriteName(nameof(value.Representation));
context.Writer.WriteInt32((int)value.Representation);
context.Writer.WriteEndDocument();
}
public bool TryGetMemberSerializationInfo(string memberName, out BsonSerializationInfo serializationInfo)
{
switch (memberName)
{
case "Representation":
serializationInfo = new BsonSerializationInfo("Representation", new EnumSerializer<State>(), typeof(State));
return true;
default:
serializationInfo = null;
return false;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.