【问题标题】:Unknown discriminator value 'MyEvent'未知的鉴别器值“MyEvent”
【发布时间】:2011-11-19 01:37:40
【问题描述】:

joliver/EventStore 中使用 MongoDB 持久性引擎导致错误 Unknown discriminator value 'MyEvent'。仅当我尝试加载所有事件以重播 this.storeEvent.Advanced.GetFrom(new DateTime(2010, 1,1)) 等事件时才会出现此问题@

问题是在 ExtensionsMethods.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();

但是已经尝试了几乎所有类型的序列化程序选项。

【问题讨论】:

    标签: mongodb-.net-driver event-sourcing neventstore


    【解决方案1】:

    我也遇到了这个。 Zsolt's 答案是一个很好的起点,但我最终解决的问题略有不同。

    请注意,我不仅在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&lt;TypeToMap&gt; 效果更好,因为这需要泛型类型参数,这意味着您必须使用 manually add each event type

    【讨论】:

    • 优秀的面向未来的想法,只有一些小字/警告 a) 所有 SimpleCQRS.Event 子类将被不加选择地添加,并且 b) 所有 Known Type 子类必须位于同一个大会。
    【解决方案2】:

    尝试使用 BsonClassMap.RegisterClassMap 方法注册您的对象(事件消息本身以及 EventStore 有效负载的主题)。似乎 EventStore 的 mongo 扩展可以很好地处理字符串有效负载,但不能很好地处理反序列化的对象……至少注册分类是我的解决方案。

    【讨论】:

    • 谢谢。当我保存提交时,mongo db 驱动程序自己注册了类,但是在回复(纯阅读)时,映射没有完成。
    • 谢谢,虽然我不明白为什么需要这样做
    猜你喜欢
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 2013-06-16
    • 1970-01-01
    相关资源
    最近更新 更多