using System; using System.Diagnostics; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; using MongoDB.Driver; namespace MongoDB.Test { [BsonDiscriminator(RootClass = true)] public class User { public User(string name, int age) { Name = name; Age = age; } [BsonId] public ObjectId Id { get; set; } public string Name { get; set; } public int Age { get; set; } public override string ToString() => $@"{GetType().Name}: {Name} ({Age})"; } public class Citizen : User { public Citizen(string name, int age, string socialSecurityNumber) : base(name, age) { SocialSecurityNumber = socialSecurityNumber; } public string SocialSecurityNumber { get; set; } public override string ToString() => $@"{base.ToString()} - {SocialSecurityNumber}"; } class Program { static void Main() { var mongoUrl = MongoUrl.Create(@"mongodb://localhost:30000/test"); var client = new MongoClient(mongoUrl); client.DropDatabase(mongoUrl.DatabaseName); var database = client.GetDatabase(mongoUrl.DatabaseName); var collection = database.GetCollection(nameof(User)); // #1 - Inserting a Citizen work just fine. The "_t" discriminator if fully populated var user = new Citizen("Kane", 42, "12345678"); collection.InsertOne(user); Debug.WriteLine("--- #1 Citizens ---"); Debug.WriteLine(string.Join(Environment.NewLine, collection.Find(_ => true).ToList())); // #2 - Making an upsert using "OfType<>" fails to generate a full "_t" disciminator var filter = Builders.Filter.Eq(_ => _.Name, "Martin") & Builders.Filter.Eq(_ => _.SocialSecurityNumber, "55667788"); var update = Builders.Update.Set(_ => _.Age, 43); collection.OfType().UpdateOne(filter, update, new UpdateOptions { IsUpsert = true }); // #3 - Reveiled by using e.g this (Citizen Martin, is not fetched from db) Debug.WriteLine("--- #3 Citizens ---"); Debug.WriteLine(string.Join(Environment.NewLine, collection.OfType().Find(_ => true).ToList())); // #4 - This works - off cause Debug.WriteLine("--- #4 Citizens ---"); Debug.WriteLine(string.Join(Environment.NewLine, collection.Find(_ => true).ToList())); } } }