8

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();

しかし、ほぼすべての種類のシリアライザーオプションを試しました。

4

2 に答える 2

13

私もこれに遭遇しました。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>は、ジェネリック型パラメーターが必要なためです。つまり、各イベント type を手動で追加する必要があります。

于 2012-07-31T15:12:21.117 に答える
10

BsonClassMap.RegisterClassMapメソッドを使用して、オブジェクト(それ自体がイベントメッセージとEventStoreペイロードのサブジェクト)を登録してみてください。EventStoreのmongo拡張機能は文字列ペイロードを適切に処理するようですが、逆シリアル化されたオブジェクトは処理しません...少なくともクラス化されたものを登録することが私の場合の解決策でした。

于 2011-09-17T12:44:03.973 に答える