|
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