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

Consider supporting client side projections with Find and Select in LINQ3

    • Type: Icon: Improvement Improvement
    • Resolution: Done
    • Priority: Icon: Unknown Unknown
    • 3.0.0
    • Affects Version/s: 2.21.0
    • Component/s: LINQ3
    • None
    • Fully Compatible
    • Needed
    • 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?

      Client-side projections are not enabled by default. A user can enable them by setting the `EnableClientSideProjections` property of `ExpressionTranslationOptions`.

      Show
      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? Client-side projections are not enabled by default. A user can enable them by setting the `EnableClientSideProjections` property of `ExpressionTranslationOptions`.

      The following works in LINQ2 but not in LINQ3:

       var find = collection
           .Find(x => x.Id == 1)
           .Project(x => new { R = MyFunction(x.X) }); // MyFunction cannot be translated to MQL
      

      The following doesn't work with either LINQ provider:

      var queryable = collection.AsQueryable()
          .Where(x => x.Id == 1)
          .Select(x => new { R = MyFunction(x.X) }); // MyFunction cannot be translated to MQL
      

      When writing the new LINQ3 provider we made the deliberate decision to not support implicit client side projections for the following reasons:

      • they only work on the final Select
      • adding any additional stages after a final Select with implicit client side projections breaks the query
      • they can hide inefficiency because more data than expected might be fetched to the client

      We felt that client side projections should be explicit so that users writing and reading code know exactly what is happening server side and what is happening client side.

      The above two examples can be refactored to use explicit client side projections as follows:

      var find = collection
          .Find(x => x.Id == 1)
          .ToEnumerable() // execute the rest of this chain client side
          .Select(x => new { R = MyFunction(x.X) });
      

      and

      var enumerable = collection.AsQueryable()
          .Where(x => x.Id == 1)
          .AsEnumerable() // execute the rest of this chain client side
          .Select(x => new { R = MyFunction(x.X) });
      

      While our decision to not support implicit client side projections is reasonable, nonetheless it is a breaking change from LINQ2 (at least with respect to `Find`). In addition, in spite of the potential inefficiencies that implicit client side projections might hide some users want the convenience of it anyway.

            Assignee:
            robert@mongodb.com Robert Stam
            Reporter:
            robert@mongodb.com Robert Stam
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: