Note that there are some explanatory texts on larger screens.

plurals
  1. POMongoDB Deserialization With Discriminator Issue
    primarykey
    data
    text
    <p>I have the following classes:</p> <pre><code>[BsonIgnoreExtraElements] public class WidgetCollection { [BsonId] public int AccountId { get; set; } public ReadOnlyCollection&lt;Widget&gt; 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; } } </code></pre> <p>An example of an instance of this in the DB:</p> <pre><code>{ "_id" : 2993644, "Widgets" : [ { "_t" : "Widget", "_id" : ObjectId("504797b327e10b1e80c838ac"), "Title" : "My Notes", "Position" : 1, "Kind" : 0, "IsActive" : true } ] } </code></pre> <p>I then have an aggregation command that filters out elements in the "Widgets" array to return only elements whose "IsActive" is true. In this case, the command just returns the whole object. </p> <pre><code>var command = new CommandDocument { {"aggregate", "myCollection" }, {"pipeline", commandArray } }; var result = database.RunCommandAs&lt;AggregateResult&lt;WidgetCollection&gt;&gt;(command).Result; return result; </code></pre> <p>This is the AggregateResult class:</p> <pre><code>public class AggregateResult&lt;T&gt; : CommandResult { public T Result { get { var result = Response["result"].AsBsonArray.SingleOrDefault().AsBsonDocument; return BsonSerializer.Deserialize&lt;T&gt;(result); } } } </code></pre> <p>Yes, I know that SingleOrDefault().AsBsonDocument could case a NRE, but that's not the issue right now. I have debugged the code up to the point of deserialization and have verified that the "result" variable contains the exact same BSON as I showed above. I receive this message when trying to deserialize the result: "An error occurred while deserializing the Widgets property of class Community.Widgets.WidgetCollection: Expected element name to be '_v', not '_id'".</p> <p>Why is the deserializer expected a '_v' element?</p> <p><b>UPDATE</b><br/> I fixed the above problem by changed the type of the Widgets property to <code>ICollection</code>. I am now receiving this error: <code>Unknown discriminator value 'Widget'.</code> To me, this makes no sense since the doc has the <code>"_t" : "Widget"</code> element. </p> <p>I also tried inserting a derived class, after which the "_t" element's value was now <code>"[ "Widget", "DerivedClass"]</code> as expected, and I get the same error. Again, this does not happen when using <code>database.FindOneAs&lt;>()</code>, only when explicitly using <code>BsonSerializer.Deserialize&lt;>()</code>. I tried adding this code right before calling <code>Deserialize()</code>:</p> <pre><code>BsonClassMap.RegisterClassMap&lt;Widget&gt;(cm =&gt; { cm.AutoMap(); cm.SetIsRootClass(true); }); BsonClassMap.RegisterClassMap&lt;RssFeedWidget&gt;(); </code></pre> <p>But I am not exactly sure where that initialization code should go, and I thought it was not needed if I was using discriminator attributes on my classes.</p> <p><b>Here is my aggregation command</b><br/></p> <pre><code>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&lt;AggregateResult&lt;WidgetCollection&gt;&gt;(command).Result; </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload