[BsonIgnoreExtraElements]
[DebuggerDisplay("{Term}, Rule Status = {_ruleStatus}, Current Step = {_currentProcessingStep}")]
public class SearchTermInfo : AMongoConnectedObject
{
[BsonElement("CurrentProcessingStep")]
private ProcessingStep _currentProcessingStep;
[BsonElement("RuleStatus")]
private RuleStatus _ruleStatus;
[BsonDateTimeOptions(Kind = DateTimeKind.Local)]
public DateTime AddDateTime { get; set; }
[BsonIgnore]
[JsonIgnore]
public ProcessingStep CurrentProcessingStep
{
get => _currentProcessingStep;
set => AddHistoryRecord(value);
}
[BsonIgnore]
[JsonIgnore]
public RuleStatus RuleStatus
{
get => _ruleStatus;
set => AddHistoryRecord(value);
}
FilterDefinition<SearchTermInfo> filter = Builders<SearchTermInfo>.Filter.And(
Builders<SearchTermInfo>.Filter.Eq(a => a.Id, recordId),
Builders<SearchTermInfo>.Filter.Or(
Builders<SearchTermInfo>.Filter.Eq(a => a.CurrentProcessingStep, currentStep),
Builders<SearchTermInfo>.Filter.Exists("CurrentProcessingStep", false)
)
);
Builders<SearchTermInfo>.Filter.Eq("CurrentProcessingStep", currentStep),
UpdateResult results =
searchTermInfoCollection.MongoCollection.UpdateOne(filter, update, null, cancellationToken);
? ex{"Unable to determine the serialization information for a => a.CurrentProcessingStep."} Data: {System.Collections.ListDictionaryInternal} HResult: -2146233079 HelpLink: null InnerException: null Message: "Unable to determine the serialization information for a => a.CurrentProcessingStep." Source: "MongoDB.Driver" StackTrace: " at MongoDB.Driver.ExpressionFieldDefinition`2.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry, Boolean allowScalarValueForArrayField) at MongoDB.Driver.SimpleFilterDefinition`2.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)\r\n at MongoDB.Driver.OrFilterDefinition`1.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)\r\n at MongoDB.Driver.AndFilterDefinition`1.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)\r\n at MongoDB.Driver.MongoCollectionImpl`1.ConvertWriteModelToWriteRequest(WriteModel`1 model, Int32 index)\r\n at System.Linq.Enumerable.<SelectIterator>d__5`2.MoveNext()\r\n at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)\r\n at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)\r\n at MongoDB.Driver.Core.Operations.BulkMixedWriteOperation..ctor(CollectionNamespace collectionNamespace, IEnumerable`1 requests, MessageEncoderSettings messageEncoderSettings)\r\n at MongoDB.Driver.MongoCollectionImpl`1.CreateBulkWriteOperation(IEnumerable`1 requests, BulkWriteOptions options)\r\n at MongoDB.Driver.MongoCollectionImpl`1.BulkWrite(IClientSessionHandle session, IEnumerable`1 requests, BulkWriteOptions options, CancellationToken cancellationToken)\r\n at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass23_0.<BulkWrite>b__0(IClientSessionHandle session)\r\n at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSession[TResult](Func`2 func, CancellationToken cancellationToken)\r\n at MongoDB.Driver.MongoCollectionImpl`1.BulkWrite(IEnumerable`1 requests, BulkWriteOptions options, CancellationToken cancellationToken)\r\n at MongoDB.Driver.MongoCollectionBase`1.UpdateOne(FilterDefinition`1 filter, UpdateDefinition`1 update, UpdateOptions options, Func`3 bulkWrite)\r\n at MongoDB.Driver.MongoCollectionBase`1.UpdateOne(FilterDefinition`1 filter, UpdateDefinition`1 update, UpdateOptions options, CancellationToken cancellationToken)\r\n at SaFileIngestion.FileProcessorEngine.LockRecord(Int64 recordId, ProcessingStep currentStep, CancellationToken cancellationToken) in D:\\[FilePath]\\SaFileIngestion\\FileProcessorEngine.cs:line 195" TargetSite: {MongoDB.Driver.RenderedFieldDefinition`1[TField] Render(MongoDB.Bson.Serialization.IBsonSerializer`1[TDocument], MongoDB.Bson.Serialization.IBsonSerializerRegistry, Boolean)}
{ "_id" : NumberLong(0), "Visits" : NumberLong(498), "UpdateDateTime" : ISODate("2019-05-07T19:14:37.987+0000"), "Term" : "harry potter", "AddDateTime" : ISODate("2018-12-07T20:44:13.637+0000"), "RuleStatus" : NumberInt(1), "CurrentProcessingStep" : NumberInt(1), "LastAtgCheckDateTime" : ISODate("2019-04-22T23:34:15.155+0000"), "LastFetchCheckDateTime" : ISODate("2019-04-16T18:49:36.493+0000"), "PrimaryEan" : NumberLong(9780545596275), "PrimaryWorkId" : NumberLong(1114540338), "LastRuleValidationDateTime" : ISODate("2019-04-22T21:33:13.023+0000"), "LastAugmentation" : ISODate("2019-04-15T19:58:28.370+0000"), "WorkIds" : [ NumberLong(1108948862), NumberLong(1110118103), NumberLong(1114540739), NumberLong(12288041), NumberLong(25097628), NumberLong(6291175), NumberLong(1100042956), NumberLong(7566695), NumberLong(1013876081), NumberLong(27547356), NumberLong(1100178339), NumberLong(1004338523), NumberLong(1004395694), NumberLong(1102662272), NumberLong(1110292748), NumberLong(1100079342), NumberLong(1100036321), NumberLong(1008655339), NumberLong(1104403088), NumberLong(1107819500), NumberLong(1104510835), NumberLong(1100178133), NumberLong(1100041270), NumberLong(1113898358) ], "LastExportDateTime" : ISODate("2019-04-15T19:01:42.949+0000")}Hi Marc,
Apologies for confusion on this thread. Bob is a community user trying to help with your issue and does not work for MongoDB, Inc.
The current release of the .NET driver is indeed 2.8.0, but unfortunately it looks like the driver documentation has not been updated to reflect this yet. The minimum .NET version requirement for this is 4.5.2, however newer .NET versions are also supported. There is also a beta release of the next version of the .NET driver (2.9.0-beta1), which is the version that will be released with the MongoDB 4.2 server.
My question, shouldn’t BsonElementNameAttribute set both the ElementName and the MemberName to be the value of the elementName string provided in the attribute declaration? In this case “CurrentProcessingStep”
The BsonElementNameAttribute is used to control what element name will be used in the resulting Bson document. The MemberName will always be the actual name of the field. As you may be aware from debugging the MongoDB driver code, due to the [BsonIgnore] attribute on the CurrentProcessingStep field, it is not included in the class map and therefore not available for use in a strongly typed filter.
How can I fix this mapping?
Without knowing the behaviour of the AddHistoryRecord method, are you able to use the public properties of the SearchTermInfo object for serialization, instead of attempting to use the private member variables?
Kind Regards,
John Murphy
Hi Marc,
Does something like these attributes exist?
Not exactly. If your class implements ISupportInitialize, the driver will call the BeginInit method before deserialization and the EndInit method upon completion. This could allow you to set a flag that will control the use of the AddHistoryRecord method.
An alternate, possibly cleaner way, would be to provide a private constructor for the MongoDB C#/.NET driver to use when creating a SearchTermInfo object during deserialization. To implement this creation customisation, you would simply need to have a private constructor that sets the _currentProcessingStep and _ruleStatus fields, followed by decorating the private constructor with the [BsonConstructor] attribute.
Example code would look like:
[DebuggerDisplay("{Term}, Rule Status = {_ruleStatus}, Current Step = {_currentProcessingStep}")]
public class SearchTermInfo : AMongoConnectedObject
{
private ProcessingStep _currentProcessingStep;
private RuleStatus _ruleStatus;
public SearchTermInfo() { }
[BsonConstructor]
private SearchTermInfo(ProcessingStep currentProcessingStep, RuleStatus ruleStatus)
{
_currentProcessingStep = currentProcessingStep;
_ruleStatus = ruleStatus;
}
[BsonDateTimeOptions(Kind = DateTimeKind.Local)]
public DateTime AddDateTime { get; set; }
public ProcessingStep CurrentProcessingStep
{
get => _currentProcessingStep;
set => AddHistoryRecord(value);
}
public RuleStatus RuleStatus
{
get => _ruleStatus;
set => AddHistoryRecord(value);
}
}
Why wasn’t a way designed to allow a mapping to be added to the strongly typed filter?
Deserialization leverages reflection in a lot of places, so there is currently no concept of an exposed map for member field names.
Is there any way to extend the serialization code to add a new mapping, without redesigning the whole process?
The areas of serialization that can be customised are outlined in the member customisation documentation. If you have more advanced use cases we provide the ability to implement a custom serializer, whereby you can completely control what happens during serialization/deserialization.
Hopefully this provides some useful information for you, please let me know if you have further questions.
Kind Regards,
John Murphy