-
Type: Bug
-
Resolution: Unresolved
-
Priority: Major - P3
-
None
-
Affects Version/s: 2.12.0
-
Component/s: API, BSON, Serialization
-
Environment:TargetFramework: .NET 5
OS: Windows 10
MongoDB: Community Edition 4.4.3 2008R2Plus SLL (64 bit) - installed as Windows Service
The default discriminator conventions (ie. HierarchicalDiscriminatorConvention) don't work properly with generic types. Trying to find/insert documents with varying generic types will cause an exception "Ambiguous discriminator 'Type`1'.".
The problem and solution is also explained in this stackoverflow post: https://stackoverflow.com/questions/25891373/mongodb-c-sharp-driver-type-discriminators-with-generic-class-inheriting-from-no
The problem seems to be, that the default discriminator conventions use the type's Name property instead of its FullName or AssemblyQualifiedName property.
For some reason, using FullName will throw an exception: "Unknown discriminator value ...', while AssemblyQualifiedName works.
This is also what causes this older issue: https://jira.mongodb.org/browse/CSHARP-1240
The fix for my application was creating a custom discriminator convention that inherits from HierarchicalDiscriminatorConvention and return:
classMap.ClassType.AssemblyQualifiedName
instead of:
classMap.Discriminator
inside of the GetDiscriminator method.
see: https://github.com/mongodb/mongo-csharp-driver/blob/v2.12.x/src/MongoDB.Bson/Serialization/Conventions/HierarchicalDiscriminatorConvention.cs
Solution/suggestion:
The problem seems to be, that inside of BsonClassMap.cs, the _discriminator field is assigned a wrong value:
_discriminator = _classType.Name;
Because of the usage of _classType.Name, the discriminator conventions won't work for generic types.
A quick fix could be to instead assign AssemblyQualifiedName:
_discriminator = _classType.AssemblyQualifiedName;
in turn, the default discriminator conventions that access
classMap.Discriminator
will now receive the correct name.
I'm not sure why FullName does not work, it should be investigated whether it is better to use it over AssemblyQualifiedName.
- causes
-
CSHARP-1240 Type name store in the _t field missing generic type argument
- Closed
- is depended on by
-
CSHARP-3989 oDATA $select support with LINQ3
- Closed
- is duplicated by
-
CSHARP-1240 Type name store in the _t field missing generic type argument
- Closed