|
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