-
Notifications
You must be signed in to change notification settings - Fork 1.3k
CSHARP-5779: Support Dictionary Keys and Values properties #1807
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| return new AstComputedDocumentExpression(fields); | ||
| } | ||
|
|
||
| public static AstExpression ComputedDocument(IEnumerable<(string Name, AstExpression Value)> fields) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A more convenient overload of ComputedDocument.
| } | ||
| } | ||
|
|
||
| internal class DictionaryKeyCollectionSerializer<TKey, TValue> : EnumerableSerializerBase<Dictionary<TKey, TValue>.KeyCollection> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need a serializer for Dictionary<TKey, TValue>.KeyCollection to be able to work with this type in LINQ queries or to deserialize them client-side.
| } | ||
| } | ||
|
|
||
| internal class DictionaryValueCollectionSerializer<TKey, TValue> : SerializerBase<Dictionary<TKey, TValue>.ValueCollection>, IBsonArraySerializer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need a serializer for Dictionary<TKey, TValue>.ValueCollection to be able to work with this type in LINQ queries or to deserialize them client-side.
| } | ||
| } | ||
|
|
||
| internal class DictionarySerializer<TKey, TValue> : DictionarySerializerBase<Dictionary<TKey, TValue>, TKey, TValue> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a more convenient way to create a serializer for Dictionary<TKey, TValue>.
| } | ||
| } | ||
|
|
||
| internal class ICollectionSerializer<TItem> : EnumerableSerializerBase<ICollection<TItem>> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a more convenient way to create a serializer for ICollection<TItem>.
| } | ||
| } | ||
|
|
||
| internal class KeyValuePairWrappedValueSerializer<TKey, TValue> : SerializerBase<TValue>, IWrappedValueSerializer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a special serializer that deserializes a KeyValuePair but then extracts only the Value portion of it as the result.
It also represents values that are still coupled with the corresponding key as needed to work with a Dictionary<TKey, TValue>.ValueCollection.
| { | ||
| // public static methods | ||
| public static TranslatedExpression Translate(TranslationContext context, Expression expression) | ||
| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whenever we want to use a value we go ahead and unwrap it if it is wrapped.
|
|
||
| var ast = AstExpression.ObjectToArray(aggregateExpression.Ast); | ||
| var ienumerableSerializer = ArraySerializerHelper.CreateSerializer(keyValuePairSerializer); | ||
| var arrayOfDocumentsDictionarySerializer = DictionarySerializer.Create(DictionaryRepresentation.ArrayOfDocuments, keySerializer, valueSerializer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We were creating the "wrong" serializer before.
| case "Values": | ||
| if (declaringTypeDefinition == typeof(Dictionary<,>)) | ||
| { | ||
| var kvpPairsAst = dictionaryRepresentation switch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tricky part about supporting Values is that we have to keep the keys that go with them, at least until some later time where the keys might no longer be needed.
| } | ||
| else if (declaringTypeDefinition == typeof(IDictionary<,>)) | ||
| { | ||
| var valuesAst = dictionaryRepresentation switch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Supporting Values for IDictionary<TKey, TValue> is MUCH more straightforward because the type is ICollection<TValue>.
| case "Keys": | ||
| var keysAst = dictionaryRepresentation switch | ||
| { | ||
| DictionaryRepresentation.ArrayOfDocuments => AstExpression.Map(containerAst, kvpVar, AstExpression.GetField(kvpVar, "k")), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the time we get here we will never encounter DictionaryRepresentation.Document, because the call to TranslateEnumerable on line 204 above will have already used $objectToArray to transform the representation from Document to ArrayOfDocuments.
No description provided.