-
Type: Bug
-
Resolution: Unresolved
-
Priority: Major - P3
-
None
-
Affects Version/s: 2.9.2
-
Component/s: Serialization
-
Labels:None
-
Environment:Windows
Even though this issue is closely related to CSHARP-485, consider this small unit-test.
using System; using System.Threading.Tasks; using Mongo2Go; using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Conventions; using MongoDB.Driver; using Xunit;namespace IntegrationTest { public class MongoTestHelper : IDisposable { private readonly MongoDbRunner _runner; private readonly IMongoDatabase _db; public MongoTestHelper(string databaseName, bool debug = false) { if (debug) { _runner = MongoDbRunner.StartForDebugging(); } else { _runner = MongoDbRunner.Start(); } var mongo = new MongoClient(_runner.ConnectionString); _db = mongo.GetDatabase(databaseName); } public IMongoDatabase GetDatabase() { return _db; } public void Dispose() { _runner.Dispose(); } } public class AnimalTests : IDisposable { private readonly MongoTestHelper _helper; public AnimalTests() { var conventionPack = new ConventionPack { new IgnoreExtraElementsConvention(true) }; ConventionRegistry.Register("IgnoreExtraElements", conventionPack, type => true); BsonClassMap.RegisterClassMap<Dog>(); BsonClassMap.RegisterClassMap<Cat>(); // var dogSerializer = BsonSerializer.LookupSerializer<Dog>(); // BsonSerializer.RegisterSerializer<IAnimal>(new ImpliedImplementationInterfaceSerializer<IAnimal, Dog>(dogSerializer)); // // var catSerializer = BsonSerializer.LookupSerializer<Cat>(); // BsonSerializer.RegisterSerializer<IAnimal>(new ImpliedImplementationInterfaceSerializer<IAnimal, Cat>(catSerializer)); // // because: // MongoDB.Bson.BsonSerializationException : There is already a serializer registered for type IAnimal. _helper = new MongoTestHelper("db_test", true); } [Fact] public async Task Some_Test() { var animals = new IAnimal[] { new Dog(), new Cat() }; var db = _helper.GetDatabase(); db.DropCollection("animal"); var collWrite = db.GetCollection<IAnimal>("animal"); collWrite.InsertMany(animals); var collRead = db.GetCollection<IAnimal>("animal"); // THIS WORKS await (await collRead.FindAsync(x => true)).ToListAsync(); // THIS DOESN'T await (await collRead.FindAsync(x => x.Type == "dog")).ToListAsync(); } public void Dispose() { _helper.Dispose(); } public interface IAnimal { string Type { get; set; } string Speak { get; set; } } public class Dog : IAnimal { public string Type { get; set; } public string Speak { get; set; } public Dog() { Type = "dog"; Speak = "woof"; } } public class Cat : IAnimal { public string Type { get; set; } public string Speak { get; set; } public Cat() { Type = "cat"; Speak = "meow"; } } } }
It fails with error:
Message:
System.InvalidOperationException : {document}.Type is not supported.
Stack Trace:
PredicateTranslator.GetFieldExpression(Expression expression)
PredicateTranslator.TranslateComparison(Expression variableExpression, ExpressionType operatorType, ConstantExpression constantExpression)
PredicateTranslator.Translate(Expression node)
PredicateTranslator.Translate(Expression node, IBsonSerializerRegistry serializerRegistry)
MongoCollectionImpl`1.CreateFindOperation[TProjection](FilterDefinition`1 filter, FindOptions`2 options)
MongoCollectionImpl`1.FindAsync[TProjection](IClientSessionHandle session, FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken)
<>c__DisplayClass43_0`1.<FindAsync>b__0(IClientSessionHandle session)
MongoCollectionImpl`1.UsingImplicitSessionAsync[TResult](Func`2 funcAsync, CancellationToken cancellationToken)
AnimalTests.Some_Test() line 92
--- End of stack trace from previous location where exception was thrown ---
The difference is two concrete classes that use interface IAnimal. For that reason, I can't use the explicit serializer registration.
Though this example is contrived, it reflects a real world problem I was hoping to solve.
In the meantime, I've had to resort to a plan BSON search:
var filter = new BsonDocument {{"Type", "dog"}};