First of all, it help to understand where the "_t" is coming from. It
is a discriminator value used to record the actual type of the object
that was serialized to BSON. The _t element is only written out when
it appears to be needed, which is basically whenever polymorphism
comes into play. In the terminology of the official C# driver, the _t
element is written when the actualType is different from the
nominalType.
The reason your query is being generated with a _t is because the
actualType of the wrapped object is different from the nominalType.
BsonDocument.Wrap(obj);
is actually equivalent to:
BsonDocument.Wrap<object>(obj);
because the compiler infers the <T> type argument from the argument
supplied. So the nominalType is object, and the actualType is some
subclass of object.
Because you are working at a metadata level you can't supply the <T>
value at compile time, because you don't know it. Instead you can use
a lower level way to create a BsonDocumentWrapper:
new BsonDocumentWrapper(obj.GetType(), obj); // set nominalType to
actual type of obj to prevent _t from being serialized
It's usually much easier than this! It's just made harder by working
at a metadata level.
On a related note, I'm not sure why your documents in the database
don't have a _t element. The Insert statement you showed should have
resulted in a _t element being added because the nominalType was
object and the actualType was some subclass of object. Is there
anywhere else you are inserting documents? You can use the mongo shell
to verify what the documents actually look like in the database.