Details
-
Bug
-
Resolution: Unresolved
-
Major - P3
-
None
-
2.9.2
-
None
-
Windows
Description
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"}}; |