Mam następujących klas:MongoDB Deserializacji Z dyskryminacyjne Emisji
[BsonIgnoreExtraElements]
public class WidgetCollection
{
[BsonId]
public int AccountId { get; set; }
public ReadOnlyCollection<Widget> Widgets { get; set; }
}
[BsonIgnoreExtraElements]
[BsonDiscriminator(RootClass = true)]
[BsonKnownTypes(typeof(OtherObject1), ...)]
public class Widget
{
public ObjectId Id { get; set; }
public string Title { get; set; }
public int Position { get; set; }
public WidgetKind Kind { get; set; }
public bool IsActive { get; set; }
}
przykładem instancji to w PB:
{ "_id" : 2993644, "Widgets" : [ { "_t" : "Widget", "_id" : ObjectId("504797b327e10b1e80c838ac"), "Title" : "My Notes", "Position" : 1, "Kind" : 0, "IsActive" : true } ] }
Mam następnie polecenie agregacji który odfiltrowuje elementy w tablica "Widgety", która zwraca tylko te elementy, których "IsActive" jest prawdziwe. W takim przypadku polecenie właśnie zwraca cały obiekt.
var command = new CommandDocument
{
{"aggregate", "myCollection" },
{"pipeline", commandArray }
};
var result = database.RunCommandAs<AggregateResult<WidgetCollection>>(command).Result;
return result;
Jest to klasa AggregateResult:
public class AggregateResult<T> : CommandResult
{
public T Result
{
get
{
var result = Response["result"].AsBsonArray.SingleOrDefault().AsBsonDocument;
return BsonSerializer.Deserialize<T>(result);
}
}
}
Tak, wiem, że SingleOrDefault() AsBsonDocument mogłoby to przypadku NRE, ale to nie jest problem w tej chwili.. Debugowałem kod do momentu deserializacji i zweryfikowałem, że zmienna "result" zawiera dokładnie to samo BSON, co pokazałem powyżej. Otrzymuję tę wiadomość podczas próby deserializacji wyniku: "Wystąpił błąd podczas deserializacji właściwości Widgets klasy Community.Widgets.WidgetCollection: Oczekiwano nazwy elementu jako" _v ", a nie" _id "".
Dlaczego spodziewa się, że deserializator będzie elementem "_v"?
UPDATE
Naprawiłem powyższy problem przez zmieniony typ nieruchomości widżety ICollection
. Otrzymuję teraz ten błąd: Unknown discriminator value 'Widget'.
Dla mnie to nie ma sensu, ponieważ dokument ma element "_t" : "Widget"
.
Próbowałem również wstawiania klasy pochodnej, po której wartość elementu "_t" był teraz "[ "Widget", "DerivedClass"]
zgodnie z oczekiwaniami, i pojawia się ten sam błąd. Ponownie, nie dzieje się tak podczas korzystania z database.FindOneAs<>()
, tylko wtedy, gdy jawnie używa się BsonSerializer.Deserialize<>()
. Próbowałem dodać ten kod tuż przed wywołaniem Deserialize()
:
BsonClassMap.RegisterClassMap<Widget>(cm => { cm.AutoMap(); cm.SetIsRootClass(true); });
BsonClassMap.RegisterClassMap<RssFeedWidget>();
Ale nie jestem do końca pewien, gdzie ten kod inicjujący powinien iść, i myślałem, że to nie było potrzebne, jeśli używałem dyskryminator atrybuty na moich zajęciach.
Oto moja komenda agregacja
BsonDocument documentMatch = new BsonDocument{{"$match", new BsonDocument{{"_id", documentId}}}};
BsonDocument unwindArray = new BsonDocument{{"$unwind", "$Widgets"}};
BsonDocument arrayMatch = new BsonDocument{{"$match", new BsonDocument{{"Widgets.IsActive", true}}}});
BsonArray commandArray = new BsonArray();
commandArray.Add(documentMatch);
commandArray.Add(unwindArray),
commandArray.Add(arrayMatch);
var command = new CommandDocument
{
{"aggregate", collectionName},
{"pipeline", commandArray}
}
var result = database.RunCommandAs<AggregateResult<WidgetCollection>>(command).Result;
Dlaczego nie idziesz o krok dalej i nie próbujesz samodzielnie debugować sterownika?Kod źródłowy jest tutaj: https://github.com/mongodb/mongo-csharp-driver –
Dobra rozmowa. Wygląda na to, że próbuje deserializować element w tablicy, szuka łańcucha _t, a następnie łańcucha _v, który nie istnieje. Próbowałem szukać tego, co jest celem elementu _v, ale nie mogę znaleźć niczego. – anthv123
Jestem trochę zdezorientowany co do tego, czego używasz w parametrze BsonSerializer.Deserialize ... Czy używasz Widget lub WidgetCollection? –