在joliver/EventStore中使用MongoDB持久性引擎导致错误Unknown discriminator value 'MyEvent'
。只有当我尝试加载所有事件以重播this.storeEvent.Advanced.GetFrom(new DateTime(2010, 1,1))
等事件时,才会出现此问题
问题是由ExtensionMethods.cs 引起的
public class MyClassEvent : IDomainEvent { ... }
public static Commit ToCommit(this BsonDocument doc, IDocumentSerializer serializer)
{
if (doc == null)
return null;
var id = doc["_id"].AsBsonDocument;
var streamId = id["StreamId"].AsGuid;
var commitSequence = id["CommitSequence"].AsInt32;
var events = doc["Events"].AsBsonArray.Select(e => e.AsBsonDocument["Payload"].IsBsonDocument ? BsonSerializer.Deserialize<EventMessage>(e.AsBsonDocument["Payload"].AsBsonDocument) : serializer.Deserialize<EventMessage>(e.AsBsonDocument["Payload"].AsByteArray)).ToList();
var streamRevision = doc["Events"].AsBsonArray.Last().AsBsonDocument["StreamRevision"].AsInt32;
return new Commit(
streamId,
streamRevision,
doc["CommitId"].AsGuid,
commitSequence,
doc["CommitStamp"].AsDateTime,
BsonSerializer.Deserialize<Dictionary<string, object>>(doc["Headers"].AsBsonDocument),
events);
}
我的配置是这样的:
Wireup.Init()
.UsingMongoPersistence(connectionName, new DocumentObjectSerializer())
.UsingBsonSerialization()
.UsingAsynchronousDispatcher()
.PublishTo(this.container.Resolve<IPublishMessages>())
.Build();
但已经尝试了几乎所有类型的序列化程序选项。
我刚刚也遇到了这个问题。Zsolt的回答是一个很好的起点,但我最终解决的问题略有不同。
注意,我不仅在myEventStore.Advanced.GetFrom(...)
时得到了这个;myEventStore.OpenStream(...)
也失败。这是有道理的,因为这两个方法都使用相同的IPersistentStream
和序列化程序。
当我第一次持久化事件时,在检索相同类型的事件之前,我不会遇到这个问题。显然,当MongoDB第一次被要求序列化一个类型时,它会创建一个ClassMap
。
无论如何,对我来说,解决方案是在应用程序启动时为我的所有事件类型创建一个类映射。假设所有类型都在SimpleCQRS.Event
的集合中,并从SimpleCQRS.Event
派生,我这样做:
var types = Assembly.GetAssembly(typeof(SimpleCQRS.Event))
.GetTypes()
.Where(type => type.IsSubclassOf(typeof(SimpleCQRS.Event)));
foreach (var t in types)
BsonClassMap.LookupClassMap(t);
对我来说,这比Zsolt建议的使用BsonClassMap.RegisterClassMap<TypeToMap>
效果更好,因为这需要一个泛型类型参数,这意味着你必须手动添加每个事件类型。
尝试使用BsonClassMap.RegisterClassMap方法注册对象(本身是事件消息以及EventStore有效负载的主题(。EventStore的mongo扩展似乎能很好地处理字符串有效负载,但不能处理反序列化的对象。。。至少在我的情况下,注册分类是解决方案。