|  | 
| 19 | 19 | using System.Reflection; | 
| 20 | 20 | using MongoDB.Bson; | 
| 21 | 21 | using MongoDB.Bson.Serialization; | 
|  | 22 | +using MongoDB.Bson.Serialization.Options; | 
| 22 | 23 | using MongoDB.Bson.Serialization.Serializers; | 
| 23 | 24 | using MongoDB.Driver.Linq.Linq3Implementation.Ast.Expressions; | 
| 24 |  | -using MongoDB.Driver.Linq.Linq3Implementation.ExtensionMethods; | 
| 25 | 25 | using MongoDB.Driver.Linq.Linq3Implementation.Misc; | 
| 26 | 26 | using MongoDB.Driver.Linq.Linq3Implementation.Reflection; | 
| 27 | 27 | 
 | 
| @@ -55,9 +55,9 @@ public static TranslatedExpression Translate(TranslationContext context, Express | 
| 55 | 55 |                 return TranslateIListGetItemWithInt(context, expression, sourceExpression, arguments[0]); | 
| 56 | 56 |             } | 
| 57 | 57 | 
 | 
| 58 |  | -            if (DictionaryMethod.IsGetItemWithStringMethod(method)) | 
|  | 58 | +            if (DictionaryMethod.IsGetItemWithKeyMethod(method)) | 
| 59 | 59 |             { | 
| 60 |  | -                return TranslateIDictionaryGetItemWithString(context, expression, sourceExpression, arguments[0]); | 
|  | 60 | +                return TranslateIDictionaryGetItemWithKey(context, expression, sourceExpression, arguments[0]); | 
| 61 | 61 |             } | 
| 62 | 62 | 
 | 
| 63 | 63 |             throw new ExpressionNotSupportedException(expression); | 
| @@ -112,13 +112,55 @@ private static TranslatedExpression TranslateIListGetItemWithInt(TranslationCont | 
| 112 | 112 |             return new TranslatedExpression(expression, ast, serializer); | 
| 113 | 113 |         } | 
| 114 | 114 | 
 | 
| 115 |  | -        private static TranslatedExpression TranslateIDictionaryGetItemWithString(TranslationContext context, Expression expression, Expression sourceExpression, Expression keyExpression) | 
|  | 115 | +        private static TranslatedExpression TranslateIDictionaryGetItemWithKey(TranslationContext context, Expression expression, Expression dictionaryExpression, Expression keyExpression) | 
| 116 | 116 |         { | 
| 117 |  | -            var sourceTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, sourceExpression); | 
| 118 |  | -            var key = keyExpression.GetConstantValue<string>(containingExpression: expression); | 
| 119 |  | -            var ast = AstExpression.GetField(sourceTranslation.Ast, key); // TODO: verify that dictionary is using Document representation | 
| 120 |  | -            var valueSerializer = GetDictionaryValueSerializer(sourceTranslation.Serializer); | 
| 121 |  | -            return new TranslatedExpression(expression, ast, valueSerializer); | 
|  | 117 | +            var dictionaryTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, dictionaryExpression); | 
|  | 118 | +            if (!(dictionaryTranslation.Serializer is IBsonDictionarySerializer dictionarySerializer)) | 
|  | 119 | +            { | 
|  | 120 | +                throw new ExpressionNotSupportedException(expression, because: $"dictionary serializer class {dictionaryTranslation.Serializer.GetType()} does not implement {nameof(IBsonDictionarySerializer)}"); | 
|  | 121 | +            } | 
|  | 122 | +            if (dictionarySerializer.DictionaryRepresentation != DictionaryRepresentation.Document) | 
|  | 123 | +            { | 
|  | 124 | +                throw new ExpressionNotSupportedException(expression, because: "dictionary is not represented as a document"); | 
|  | 125 | +            } | 
|  | 126 | + | 
|  | 127 | +            var keySerializer = dictionarySerializer.KeySerializer; | 
|  | 128 | +            AstExpression keyFieldNameAst; | 
|  | 129 | + | 
|  | 130 | +            if (keyExpression is ConstantExpression constantKeyExpression) | 
|  | 131 | +            { | 
|  | 132 | +                var key = constantKeyExpression.Value; | 
|  | 133 | +                var serializedKey = SerializationHelper.SerializeValue(keySerializer, key); | 
|  | 134 | + | 
|  | 135 | +                if (!(serializedKey is BsonString)) | 
|  | 136 | +                { | 
|  | 137 | +                    throw new ExpressionNotSupportedException(expression, because: "key did not serialize as a string"); | 
|  | 138 | +                } | 
|  | 139 | + | 
|  | 140 | +                keyFieldNameAst = AstExpression.Constant(serializedKey); | 
|  | 141 | +            } | 
|  | 142 | +            else | 
|  | 143 | +            { | 
|  | 144 | +                if (!(keySerializer is IHasRepresentationSerializer hasRepresentationSerializer)) | 
|  | 145 | +                { | 
|  | 146 | +                    throw new ExpressionNotSupportedException(expression, because: $"key serializer class {keySerializer.GetType()} does not implement {nameof(IHasRepresentationSerializer)}"); | 
|  | 147 | +                } | 
|  | 148 | +                if (hasRepresentationSerializer.Representation != BsonType.String) | 
|  | 149 | +                { | 
|  | 150 | +                    throw new ExpressionNotSupportedException(expression, because: $"key serializer class {keySerializer.GetType()} does not serialize as a string"); | 
|  | 151 | +                } | 
|  | 152 | + | 
|  | 153 | +                var keyTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, keyExpression); | 
|  | 154 | +                if (!keyTranslation.Serializer.Equals(keySerializer)) | 
|  | 155 | +                { | 
|  | 156 | +                    throw new ExpressionNotSupportedException(expression, because: "key expression serializer is not equal to the key serializer"); | 
|  | 157 | +                } | 
|  | 158 | + | 
|  | 159 | +                keyFieldNameAst = keyTranslation.Ast; | 
|  | 160 | +            } | 
|  | 161 | + | 
|  | 162 | +            var ast = AstExpression.GetField(dictionaryTranslation.Ast, keyFieldNameAst); | 
|  | 163 | +            return new TranslatedExpression(expression, ast, dictionarySerializer.ValueSerializer); | 
| 122 | 164 |         } | 
| 123 | 165 |     } | 
| 124 | 166 | } | 
0 commit comments