[CSHARP-917] Dictionary serializers should implement IBsonDocumentSerializer Created: 23/Feb/14  Updated: 31/Mar/23  Resolved: 06/May/15

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: None
Fix Version/s: 2.1

Type: Improvement Priority: Minor - P4
Reporter: Stefan Assignee: Craig Wilson
Resolution: Done Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to CSHARP-2195 Equality expression translation for R... Closed
Epic Link: Rewrite Linq

 Description   

With a model like so:

public class Foo
        {
            [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfDocuments)]
            public Dictionary<string, object> Properties { get; set; }
        }

We should be able to write a query like so:

foos.Where(x => x.Properties["life"] == 42);

Cheers
Stefan



 Comments   
Comment by Robert Stam [ 29/Mar/23 ]

The dictionary serializers already implement IBsonDocumentSerializer.

Any issues LINQ3 might be having with using dictionaries would be unrelated to this and we would track them separately from this ticket.

Comment by Manuel Kugelmann [ 29/Mar/23 ]

Any hints on how that fix could look for LINQ V3? robert@mongodb.com  craig.wilson@mongodb.com  Locked to V2 because V3 is missing this functionality

Comment by Prophasi N/A [ 07/Dec/22 ]

Understood, thanks for the response. I wasn't aware of the LINQ2 vs. LINQ3 dichotomy, and I've worked around it for now by pushing the filtering logic into my Mongo repo, but I'm glad there's an official issue on the board for tracking.

Comment by Robert Stam [ 07/Dec/22 ]

Thanks for the information you have provided.

I can see from your stack trace that you are using LINQ2. LINQ2 is being replaced by LINQ3 and we are no longer enhancing LINQ2.

I have created CSHARP-4443 to investigate supporting LINQ queries against all 3 possible Dictionary representations.

Comment by Prophasi N/A [ 04/Dec/22 ]

Hey there,

Sorry to resurrect this old thread, but the example code is exactly what's breaking for me, and it wasn't solved entirely with this issue's closure (the LINQ bit was still pending, although I see the epic was since closed). I didn't see any other issues so directly pertinent.

I have a string dictionary that I'm serializing as an array of objects, via the attribute:

[BsonDictionaryOptions(DictionaryRepresentation.ArrayOfDocuments)]
public Dictionary<string, string> Entries { get; private set; } = new();

De/serialization works fine, and I was able to add a composite index (which was my goal). However, attempting to use a Expression<Func> filter, like so:

await collection.Find(x => x.Entries["TY"] == "test")

...throws this exception:

Unhandled exception: System.InvalidOperationException: x.Entries.get_Item("TY") is not supported.
   at MongoDB.Driver.Linq.Linq2Implementation.Translators.PredicateTranslator.GetFieldExpression(Expression expression)
   at MongoDB.Driver.Linq.Linq2Implementation.Translators.PredicateTranslator.TranslateComparison(Expression variableExpression, ExpressionType operatorType, ConstantExpression constantExpression)
   at MongoDB.Driver.Linq.Linq2Implementation.Translators.PredicateTranslator.TranslateComparison(BinaryExpression binaryExpression)
   at MongoDB.Driver.Linq.Linq2Implementation.Translators.PredicateTranslator.Translate(Expression node)

Using the default dictionary serializer, it works: rather than translating to x.Entries.get_Item("TY"), it becomes x.Entries.TY, which is a valid IFieldExpression (per ExpressionHelper.TryGetExpression).

Certain sources assert that this was fixed; but I don't find it so, nor does a comment on this SO post:
https://stackoverflow.com/a/36858185

Is this indeed still pending, and is it on the board for tracking, if so? Presumably I can work around it using a query builder... a bit unfortunate since my business logic's in a higher layer than my Mongo repo; but I can rework it if needed.

(I've tested this up to v2.18.0 of the driver, I should add.)

Thanks!

Comment by Githook User [ 06/May/15 ]

Author:

{u'username': u'craiggwilson', u'name': u'Craig Wilson', u'email': u'craiggwilson@gmail.com'}

Message: CSHARP-917: added support for linq queries through a dictionary.
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/d7a1e8db2207555b34b5dcb5181f2c90e07f960e

Comment by Robert Stam [ 22/Sep/14 ]

Removed from Sprint 8 and put with the rest of the LINQ tickets in the backlog.

Comment by Robert Stam [ 22/Sep/14 ]

Added this ticket to the "Rewrite LINQ" epic because implementing IBsonDocumentSerializer is only part of the work, the rest of the work is LINQ related.

Comment by Craig Wilson [ 25/Feb/14 ]

Yeah. I think first step is to implement IBsonDocumentSerializer because it's the only way to get the serialization information for each member. Once that has happened, we'll need to decide on how to render the query based on something else like the DictionaryRepresentation if it exists.

Comment by Stefan [ 25/Feb/14 ]

Implementing IBsonDocumentSerializer seems to work if the dictionary is using DictionaryRepresentation.Document, as the generated query looks like:

{ \"E.x\" : 1 }

but if we use DictionaryRepresentation.ArrayOfDocuments we still end up with the same query generated, instead of checking the key and value match.

Cheers
Stefan

Generated at Wed Feb 07 21:38:11 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.