Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-4560

UpdateManyAsync fails after upgrade to 2.19.0

    • Type: Icon: Task Task
    • Resolution: Unresolved
    • Priority: Icon: Unknown Unknown
    • None
    • Affects Version/s: None
    • Component/s: LINQ3

      After upgrading to 2.19.0 (due to the security vulnerability) we found that our integration tests fail trying to call  UpdateManyAsync with the following exception:

       

       

      Error Message:
         MongoDB.Driver.Linq.ExpressionNotSupportedException : Expression not supported: Convert(Convert(x, IRankedObj).Rank, Nullable`1).
        Stack Trace:
           at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToFilterTranslators.ToFilterFieldTranslators.ConvertExpressionToFilterFieldTranslator.Translate(TranslationContext context, UnaryExpression expression)
         at MongoDB.Driver.Linq.Linq3Implementation.LinqProviderAdapterV3.TranslateExpressionToField[TDocument,TField](Expression`1 expression, IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry, Boolean allowScalarValueForArrayField)
         at MongoDB.Driver.ExpressionFieldDefinition`2.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider, Boolean allowScalarValueForArrayField)
         at MongoDB.Driver.ExpressionFieldDefinition`2.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider)
         at MongoDB.Driver.OperatorUpdateDefinition`2.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider)
         at MongoDB.Driver.MongoCollectionImpl`1.ConvertWriteModelToWriteRequest(WriteModel`1 model, Int32 index)
         at System.Linq.Enumerable.SelectIterator[TSource,TResult](IEnumerable`1 source, Func`3 selector)+MoveNext()
         at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
         at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
         at MongoDB.Driver.Core.Operations.BulkMixedWriteOperation..ctor(CollectionNamespace collectionNamespace, IEnumerable`1 requests, MessageEncoderSettings messageEncoderSettings)
         at MongoDB.Driver.MongoCollectionImpl`1.CreateBulkWriteOperation(IClientSessionHandle session, IEnumerable`1 requests, BulkWriteOptions options)
         at MongoDB.Driver.MongoCollectionImpl`1.BulkWriteAsync(IClientSessionHandle session, IEnumerable`1 requests, BulkWriteOptions options, CancellationToken cancellationToken)
         at MongoDB.Driver.MongoCollectionBase`1.UpdateManyAsync(FilterDefinition`1 filter, UpdateDefinition`1 update, UpdateOptions options, Func`3 bulkWriteAsync)
         at ApiServer.Services.MongoDbService.<>c__DisplayClass37_0`1.<<DeleteRankObjFromId>b__0>d.MoveNext() in /builds/hydra/hydra-src/apps/API-Server/ApiServer/Services/MongoDbService.cs:line 470
      --- End of stack trace from previous location ---
         at ApiServer.Services.MongoDbService.<>c__DisplayClass30_0.<<WriteInTransaction>b__0>d.MoveNext() in /builds/hydra/hydra-src/apps/API-Server/ApiServer/Services/MongoDbService.cs:line 325
      --- End of stack trace from previous location ---
         at MongoDB.Driver.TransactionExecutor.ExecuteCallbackAsync[TResult](IClientSessionHandle clientSession, Func`3 callbackAsync, DateTime startTime, IClock clock, CancellationToken cancellationToken)
         at MongoDB.Driver.TransactionExecutor.ExecuteCallbackAsync[TResult](IClientSessionHandle clientSession, Func`3 callbackAsync, DateTime startTime, IClock clock, CancellationToken cancellationToken)
         at MongoDB.Driver.TransactionExecutor.ExecuteWithRetriesAsync[TResult](IClientSessionHandle clientSession, Func`3 callbackAsync, TransactionOptions transactionOptions, IClock clock, CancellationToken cancellationToken)
         at ApiServer.Services.MongoDbService.WriteInTransaction(Func`2 action) in /builds/hydra/hydra-src/apps/API-Server/ApiServer/Services/MongoDbService.cs:line 321
         at ApiServer.Services.MongoDbService.DeleteRankObjFromId[T](ObjectId id, String collectionName) in /builds/hydra/hydra-src/apps/API-Server/ApiServer/Services/MongoDbService.cs:line 459
         at IntegrationTests.PabxMappingTests.DeletePabxMapping_Deleted() in /builds/hydra/hydra-src/apps/API-Server/IntegrationTests/PabxMappingTests.cs:line 181
         at NUnit.Framework.Internal.TaskAwaitAdapter.GenericAdapter`1.BlockUntilCompleted()
         at NUnit.Framework.Internal.MessagePumpStrategy.NoMessagePumpStrategy.WaitForCompletion(AwaitAdapter awaiter)
         at NUnit.Framework.Internal.AsyncToSyncAdapter.Await(Func`1 invoke)
         at NUnit.Framework.Internal.Commands.TestMethodCommand.RunTestMethod(TestExecutionContext context)
         at NUnit.Framework.Internal.Commands.TestMethodCommand.Execute(TestExecutionContext context)
         at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__0()
         at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
        Standard Output Messages:
       2023-03-05T23:27:14.4711824+00:00 [MongoDbService] [Error] Failed to delete Ranked object from collection pabx_map
      2023-03-05T23:27:18.0832340+00:00 [ApiCacheUpdaterService] [Information] Initial sync complete
      2023-03-05T23:27:18.0833334+00:00 [MongoDbService] [Information] Begin watch from ts=7207207825678794752, tid=97
      2023-03-05T23:27:18.0896708+00:00 [MongoDbService] [Debug] Watch cancelled

       

       

      This is the method that calls UpdateManyAsync:

       

          public async Task DeleteRankObjFromId<T>(ObjectId id, string collectionName) where T : IStoredRankedObj
          {
              await WriteInTransaction(async session =>
              {
                  try
                  {
                      var collection = _mongoDatabase.GetCollection<T>(collectionName);
                      var cursor = await collection.FindAsync(session, rankObj => rankObj.Id == id);
                      var objectToDelete = await cursor.FirstOrDefaultAsync();  // need rank of object to be deleted to adjust others
                      if (objectToDelete != null)
                      {
                          var result = await collection.DeleteOneAsync(session, rankObj => rankObj.Id == id);
                          var updateDefinition = Builders<T>.Update.Inc(x => (int?)x.Rank, -1);
                          await collection.UpdateManyAsync(
                              session,                                     
                              existingRankObj =>
                                  existingRankObj.Rank > objectToDelete.Rank,
                              updateDefinition);
                      }
                  }
                  catch (Exception exception)
                  {
                      _logger.LogError(exception, "Failed to delete Ranked object from collection {CollectionName}", collectionName);
                      throw;
                  }
              });
          }

       

      The type T is StorePabxMapping class defined as follows:

       

       

      public record StoredPabxMapping : PabxMapping, IStoredRankedObj
      {
          public StoredPabxMapping()
          {
          }    
      
          public StoredPabxMapping(PabxMapping pabxMap)
          {
              Rank = pabxMap.Rank;
              Replace = pabxMap.Replace;
              Match = pabxMap.Match;
          }    
          
          public ObjectId Id { get; set; }
      }
      
      public record PabxMapping : IRankedObj
      {    public uint? Rank { get; set; }    [Required]
          [RegularExpression(@"^(\d+|\d*\*)$",
              ErrorMessage = "'InternalNumber' formatted incorrectly")]
          public string Match { get; set; } = "";    [Required]
          [RegularExpression(@"^(\+?\d+|\+?\d*\*)$",
              ErrorMessage = "'PhoneNumber' formatted incorrectly")]
          public string Replace { get; set; } = "";
      }
      
      public interface IRankedObj
      {
          uint? Rank { get; set; }
      }
      
      public interface IStoredRankedObj : IRankedObj
      {
          ObjectId Id { get; set; }
      }

       

            Assignee:
            Unassigned Unassigned
            Reporter:
            trampster@gmail.com Daniel Hughes
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: