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

PredicateTranslator.TranslatePipelineContains fails to parse MethodCallExpression

    • Type: Icon: New Feature New Feature
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 2.18.0
    • Affects Version/s: 2.8.0, 2.9.1
    • Component/s: Linq
    • Labels:
      None
    • Environment:
      Windows 10, Azure Cosmos DB Emulator.

      I need to perform search on the documents with a field in range of specific values.

      Having following model:

      public class Entity
      {
              public BsonDocument Body { get; set; }
      
              [BsonIgnore] public JObject BodyJson => JObject.Parse(Body.ToJson());
      
              public string Caption { get; set; }
      }
      

      With counterpart in DB:

      {
          "_id": {
              "$oid": "5c5ad9825404a952105a2c7b"
          },
          "Body": {
              "name": "Test1"
          },
          "Caption": "Entity created for testing purposes",
          "id": "5c5ad9825404a952105a2c7b",
          "_ts": 1566318353
      }
      

       
      This code works just fine:

      Expression<Func<TypeDefinition, bool>> predicate = entity => new[] { "Test1", "Test2" }.Contains(entity.Caption);
      
      IMongoDatabase.GetCollection<Entity>("entities").Find(predicate).ToListAsync();
      

      But when I try to perform search on Body contained properties (as below) - ArgumentException is being thrown:

      Expression<Func<TypeDefinition, bool>> predicate = entity => new[] { "Test1", "Test2" }.Contains((string)entity.Body["name"]);
      

      Exception details:

      System.ArgumentException: Unsupported filter: Contains(value(System.String[])).
      at MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate(Expression node)
      at MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate(Expression node, IBsonSerializerRegistry serializerRegistry)
      at MongoDB.Driver.MongoCollectionImpl`1.CreateFindOperation[TProjection](FilterDefinition`1 filter, FindOptions`2 options)
      at MongoDB.Driver.MongoCollectionImpl`1.FindAsync[TProjection](IClientSessionHandle session, FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken)
      at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass43_0`1.<FindAsync>b__0(IClientSessionHandle session)
      at MongoDB.Driver.MongoCollectionImpl`1.<UsingImplicitSessionAsync>d__101`1.MoveNext()
      at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
      at MongoDB.Driver.IAsyncCursorSourceExtensions.<ToListAsync>d__16`1.MoveNext()
      at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
      at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
      at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
      at MyProj.Repositories.EntitiesRepository.<GetLatestMinorVersionAsync>d__7.MoveNext() in C:\projects\MyProj\Repositories\EntitiesRepository.cs:line 125
      

      Taking a brief glance at PredicateTranslator, discovered that TranslatePipelineContains accepts one side of expression only as IFieldExpression. But since I'm using BsonDocument's accessor to retrieve property - MethodCallExpression is being passed:
      (System.String).Call ($entity.Body).get_Item("name")

            Assignee:
            robert@mongodb.com Robert Stam
            Reporter:
            bohdan.kobel@pl.abb.com Bohdan Kobel
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: