I updated my project MongoDb C# driver to version 3.5.0 (from 3.4.1) and I started receiving this exception:
MongoDB.Bson.BsonSerializationException: 'The discriminator element name cannot be SecurityType because it is already being used by the property SecurityType of type InfrastructureInterfaces.Models.FutureIdentifierSheet'
FutureIdentifierSheet inherit from IdentifierSheet
public record IdentifierSheet
{
public required string Identifier { get; init; }
public Security SecurityType { get; init; }
public required string Symbol { get; init; }
public Exchange Exchange { get; init; }
public string? Name { get; init; }
}
public record FutureIdentifierSheet : IdentifierSheet
{
public string Underlying { get; init; } = string.Empty;
public required DateTime ExpirationDate { get; init; }
public required string ProductCode { get; init; }
public required DateTime YearMonth { get; init; }
}
and this is my custom discriminator
private class SecurityTypeDiscriminatorConvention : IDiscriminatorConvention
{
public string ElementName => nameof(IdentifierSheet.SecurityType);
public Type GetActualType(IBsonReader bsonReader, Type nominalType)
{
var bookmark = bsonReader.GetBookmark();
bsonReader.ReadStartDocument();
var actualType = typeof(IdentifierSheet);
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
{
string? name = bsonReader.ReadName();
if (name == ElementName)
{
var enumValue = (SecurityType.Security)(object)bsonReader.ReadInt32();
actualType = enumValue switch
{
SecurityType.Security.Future => typeof(FutureIdentifierSheet),
SecurityType.Security.Option => typeof(OptionIdentifierSheet),
_ => actualType
};
break;
}
bsonReader.SkipValue();
}
bsonReader.ReturnToBookmark(bookmark);
return actualType;
}
public BsonValue GetDiscriminator(Type nominalType, Type actualType)
{
if (actualType == typeof(FutureIdentifierSheet))
return (int)SecurityType.Security.Future;
if (actualType == typeof(OptionIdentifierSheet))
return (int)SecurityType.Security.Option;
return (int)SecurityType.Security.NoSecurity; // fallback or base
}
}
the execution code after class map and discriminator registration is
var queryable = _futureSheetsCollection.AsQueryable();
var query = queryable.Where(f => identifiers.Contains(f.Identifier));
var sheets = await query.ToListAsync();
with an example document
{
"_id": {
"$oid": "68d50e6bd43281b1daa42b15"
},
"Identifier": "BBG002CYRBV9",
"SecurityType": 6,
"Symbol": "ES_H1998",
"ProductCode": "ES",
"YearMonth": {
"$date": "1998-03-01T00:00:00.000Z"
},
"Exchange": "XCME",
"Name": "E-Mini S&P 500 Future - Mar 1998",
"ExpirationDate": {
"$date": "1998-03-20T00:00:00.000Z"
},
"Notes": "1 contract -> $50 x S&P 500 Index"
}
The exception is thrown at ToListAsync().
Why I cannot use an existing property has discriminator with new driver? How to fix that?