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

MongoDB Linq Query failing with embedded document interface

    • Type: Icon: Bug Bug
    • Resolution: Cannot Reproduce
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 2.4.4, 2.5
    • Component/s: LINQ3
    • Environment:
      Windows OS / .NET Core and .NET Framework projects
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?

      Original Post: https://stackoverflow.com/questions/48470510/c-sharp-mongodb-linq-query-failing-with-embedded-document-interface

      I'm trying to use LINQ expressions to query a simple collection in MongoDB but currently I'm facing issues when the root document contains an embedded document represented by an interface in the C# model. This is happening for me at the current MonboDB C# 2.5.0 Driver.

      I've put together an example which reproduces my problem. If I have a pair of classes defined as such:

      public class MainClass
      {
          [BsonId]
          public Guid Id { get; set; }
          public String Name { get; set; }
          public InnerClass Child { get; set; }
      }
      
      public class InnerClass
      {
          public String Name { get; set; }
      }
      

      I can query it with no problems with the following Linq query:

      var entity = collection.AsQueryable<MainClass>().SingleOrDefault(x => x.Child.Name.Equals("Some Value"));
      

      However, if I change my model to the following (basically replacing straight class references with interfaces):

      public class MainClass : IMainClass
      {
          [BsonId]
          public Guid Id { get; set; }
          public String Name { get; set; }
          public IInnerClass Child { get; set; }
      }
      
      public class InnerClass : IInnerClass
      {
          public String Name { get; set; }
      }
      
      public interface IMainClass
      {
          Guid Id { get; set; }
          String Name { get; set; }
          IInnerClass Child { get; set; }
      }
      
      public interface IInnerClass
      {
          String Name { get; set; }
      }
      

      When performing the same query I get the following exception:

      System.InvalidOperationException: '{document}.Child.Name is not supported.'
      

      Both examples work just fine when queried with standard mongodb queries (either with interface or concrete class in the generic signature):

      var entity = collection.Find(Builders<IMainClass>.Filter.Eq("Child.Name", "Some Value")).SingleOrDefault();
      

      Debugging around MongoDB C# Driver source code, the problem seems to happen somewhere around the PredicateTranslator class when it tries:

      TryGetFieldExpression(expression, out fieldExpression)
      For some reason, in the failing example, the Expression node arrives with a type of "System.Linq.Expressions.PropertyExpression" which fails to cast to "MongoDB.Driver.Linq.Expressions.IFieldExpression". Meanwhile, the in the working example the Expression node arrives with a type of "MongoDB.Driver.Linq.Expressions.FieldExpression" which, of course, casts just fine to "MongoDB.Driver.Linq.Expressions.IFieldExpression".

      I was also able to verify that in both examples the expression trees arrive the same at the driver but their structure start to differ at the PipelineBinder stage.

      In the end, my question is: Is this supposed to work? Is the document modeled wrong in the first place? Any suggestions on how to get this to work?

            Assignee:
            james.kovacs@mongodb.com James Kovacs
            Reporter:
            pedro.goes Pedro Góes
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: