FieldExpressionFlattener.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /* Copyright 2015-present MongoDB Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. *
  15. */
  16. using System;
  17. using System.Linq.Expressions;
  18. using MongoDB.Driver.Linq.Expressions;
  19. namespace MongoDB.Driver.Linq
  20. {
  21. internal class FieldExpressionFlattener : ExtensionExpressionVisitor
  22. {
  23. public static Expression FlattenFields(Expression node)
  24. {
  25. var visitor = new FieldExpressionFlattener();
  26. return visitor.Visit(node);
  27. }
  28. public FieldExpressionFlattener()
  29. {
  30. }
  31. protected internal override Expression VisitArrayIndex(ArrayIndexExpression node)
  32. {
  33. var field = Visit(node.Array) as IFieldExpression;
  34. if (field != null)
  35. {
  36. var constantIndex = node.Index as ConstantExpression;
  37. if (constantIndex == null)
  38. {
  39. throw new NotSupportedException($"Only a constant index is supported in the expression {node}.");
  40. }
  41. var index = constantIndex.Value.ToString();
  42. if (index == "-1")
  43. {
  44. // We've treated -1 as meaning $ operator. We can't break this now,
  45. // so, specifically when we are flattening fields names, this is
  46. // how we'll continue to treat -1.
  47. index = "$";
  48. }
  49. return new FieldExpression(
  50. field.AppendFieldName(index),
  51. node.Serializer);
  52. }
  53. return node;
  54. }
  55. protected internal override Expression VisitDocumentWrappedField(FieldAsDocumentExpression node)
  56. {
  57. var field = Visit(node.Document) as IFieldExpression;
  58. if (field != null)
  59. {
  60. return new FieldExpression(
  61. node.PrependFieldName(field.FieldName),
  62. node.Serializer);
  63. }
  64. return node;
  65. }
  66. protected internal override Expression VisitField(FieldExpression node)
  67. {
  68. var document = Visit(node.Document) as IFieldExpression;
  69. if (document != null)
  70. {
  71. return new FieldExpression(
  72. node.PrependFieldName(document.FieldName),
  73. node.Serializer,
  74. node.Original);
  75. }
  76. return node;
  77. }
  78. }
  79. }